小熠博客1:做图表OFC的使用,以Struts1框架为例

   最近,由于项目的需要,我做了一个关于OFC与JSP结合做报表的Demo,之所以选择使用Struts框架,是因为公司的项目系统比较老用的是这个框架。
      
    首先,我必须要向我参考的文章致敬:    
    http://hi.baidu.com/javagril/item/2ca42e3501554382c2cf29d6
      
   上边这个文章虽然粘了主要的代码,但你要是直接用的话,还是会有错误,我下面会更详细的说明使用的过程,我的思路是由jsp页面开始,框架,后台。

    结合上面的文章,我想展示的是一个包括“hello worle”字符串和饼图的页面,内容如下:
<%@ page language="java" import="java.util.*" contentType="text/html; charset=UTF-8"%>
<%@include file="/jsp/inc/inc.jsp"%> 
<%-- <%@page import="snt.common.web.util.WebUtils"%> --%>
<%-- <link href="${ctxPath}/css/policy.css" rel="stylesheet" type="text/css"/> --%>
<html>
<head>
<title>OFC用例</title>
<script type="text/javascript" src="${ctxPath}/js/OFC/common.js" charset="UTF-8"></script>
<script type="text/javascript" src="${ctxPath}/js/OFC/json2.js" charset="UTF-8"></script>
<script type="text/javascript" src="${ctxPath}/js/OFC/swfobject.js" charset="UTF-8"></script>

<script type="text/javascript">
   swfobject.embedSWF(
		"${ctxPath}/jsp/ofc_test2/open-flash-chart.swf", 
		"my_piechart", 
		"40%", 
		"40%", 
		"10.0.0",
		"playerProductInstall.swf",
		{"data-file":"<%=request.getContextPath()%>/ofcTest2.do?cmd=toPieChart"},
		{wmode:"transparent"}
	);
   
   swfobject.embedSWF(
			"${ctxPath}/jsp/ofc_test2/open-flash-chart.swf", 
			"my_barchart", 
			"40%", 
			"40%", 
			"10.0.0",
			"playerProductInstall.swf",
			{"data-file":"<%=request.getContextPath()%>/ofcTest2.do?cmd=toBarChart"},
			{wmode:"transparent"}
	);

</script>
</head>
<body>
<p>Hello World</p>
<div id="my_piechart"></div>
<div id="my_barchart"></div>
</body>

</html>
  

    1.我们看到上面的jsp页面,我想之前的父页面不管是什么,我们都需要一个action来跳转到改页面,那么在编写这个action之前,我们需要的配置Struts框架的一些配置文件,这里关于Struts的东西不详细说,只是粘出源码,供参考:
    (1). action-servlet_ofcTest.xml(这个名字你随便起,只是在web.xml中配置时需要注意), 这里你们主要看的所有带“2”的文件,带“1”的文件是我用别的方法实现的用例
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
                       "http://www.springframework.org/dtd/spring-beans.dtd">
<!-- OFC用例 -->
<beans default-lazy-init="true">
    <!-- OFC1 -->
    <bean name="/ofcTest" class="snt.riskmanager.web.action.ofc_test.OFCTestAction" parent="baseAction">
            <property name="OFCTestService" ref="OFCTestService"></property>
    </bean>
    <bean name="/ofcTest2" class="snt.riskmanager.web.action.ofc_test2.OFCTestAction2" parent="baseAction">
    </bean></beans> 


    (2)struts-config_ofcTest.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN"
 "http://struts.apache.org/dtds/struts-config_1_2.dtd">

<struts-config>
 <action-mappings>
 	<!-- OFC用例-->
 	<action path="/ofcTest" type="snt.riskmanager.web.action.ofc_test.OFCTestAction" >
 		<forward name="ofcTestMain" path="/jsp/ofc_test/ofcTest.jsp"></forward>
 		<forward name="ofcTestMain2" path="/jsp/ofc_test2/ofcTest2.jsp"></forward>
 	</action>
 	action path="/ofcTest2" type="snt.riskmanager.web.action.ofc_test2.OFCTestAction2" >
 		<forward name="ofcTestMain2" path="/jsp/ofc_test2/ofcTest2.jsp"></forward></action>
 </action-mappings>
 <controller processorClass="org.springframework.web.struts.DelegatingRequestProcessor"/>
 <message-resources parameter="langres.Application"/>
</struts-config>

    
     (3)另外还应该有两个文件需要配置,一个是Struts-servlet.xml,另一个是web.xml
说白一点就是对(1)(2)这两个文件的配置。
      (4)此时如果你能访问到页面,并且看到helloworld,你的struts就ok了,不行的话找个同事儿帮看看,注意检查那个文件没有配置哦~~
      
      2.我们再来说Action,我的文件为:OFCTestAction2.java,此名字可以随便起,但是要注意改名字和路径要与action-servlet_ofcTest.xml中第二个bean的class属性值匹配,这个我说的够傻瓜了吧,其中的道理还希望自己体会。
      (1)action代码和包:
public class OFCTestAction2 extends BaseAction{
	protected ActionForward doExecute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
			// TODO Auto-generated method stub
		String cmd = request.getParameter("cmd");
		String rtn = null;
		if("ofcTestMain2".equals(cmd)){//查询所有的客户
			rtn = toofcTest2(request);
		}else if("toPieChart".equals(cmd)){
			rtn=toPieChart(response);
		}else if("toBarChart".equals(cmd)){
			rtn=toBarChart(response);
		}
		return mapping.findForward(rtn);		
	}
	
	private String toofcTest2(HttpServletRequest request) throws Exception {	
		//将结果返回到ofcTest2.jsp页面
		return "ofcTestMain2";
	}
	
    private String toPieChart(HttpServletResponse response) throws Exception {	
    	
    	PieChart   pie =   new    PieChart();

    	pie.setFontSize(15);// 设置字体

    	pie.addSlice(200000000, " 实收费用 " );// 分类

    	pie.addSlice(60000000, " 欠费金额 " );

    	pie.addSlice(30000000, " 报停金额 " );

    	pie.addSlice(20000000, " 减免金额 " );




    	pie.setStartAngle(100);// 设置角度

    	pie.setAnimate( true );

    	// 设置颜色

    	pie.setColours( new String[] { "0x336699" , "0x88AACC" , "0x999933" ,

    	"0x666699" , "0xCC9933" , "0x006666" , "0x3399FF" , "0x993300" ,

    	"0xAAAA77" , "0x666666" , "0xFFCC66" , "0x6699CC" , "0x663366" ,

    	"0x9999CC" , "0xAAAAAA" , "0x669999" , "0xBBBB55" , "0xCC6600" ,

    	"0x9999FF" , "0x0066CC" , "0x99CCCC" , "0x999999" , "0xFFCC00" ,

    	"0x009999" , "0x99CC33" , "0xFF9900" , "0x999966" , "0x66CCCC" ,

    	"0x339966" , "0xCCCC33" });

    	pie.setTooltip( "#val# / #total#<br> 占百分之 #percent#");// 鼠标移动上去后提示内容

    	pie.setRadius(20);

    	Chart flashChart = new Chart( " 2009至2010年度 包烧费分析 " , "font-size:30px;color:#ff0000;" ); // 整个图的标题 
    	//flashChart.setBackgroundColour("#3EFFFF");

    	flashChart.addElements(pie); // 把饼图加入到图表   

    	String json = flashChart.toString();// 转成 json 格式


    	response.setContentType( "application/json-rpc;charset=utf-8" );

    	response.setHeader( "Cache-Control" , "no-cache" );

    	response.setHeader( "Expires" , "0" );

    	response.setHeader( "Pragma" , "No-cache" );    

    	response.getWriter().print(json);// 写到客户端
    	
    	return null;
	}	
    
    private String toBarChart(HttpServletResponse response) throws Exception {	
    	BarChart chart = new BarChart(BarChart.Style. GLASS ); // 设置条状图样式

    	//FilledBarChart chart = new FilledBarChart("red","blue");// 设置条状图样式

    	//String sMax = "10000" ;

    	long max = 900; // //Y 轴最大值


    	Map<String,Long> map = new HashMap<String,Long>();

    	map.put( "5" , new Long(50));

    	map.put( "6" , new Long(45));

    	map.put( "7" , new Long(60));

    	map.put( "8" , new Long(30));

    	map.put( "9" , new Long(80));

    	map.put( "10" , new Long(500));

    	map.put( "11" , new Long(800));

    	map.put( "12" , new Long(200));



    	XAxis x = new XAxis(); // X 轴

    	int i = 5;

    	for (String key:map.keySet()){

    	x.addLabels(i+"月份"); // x 轴的文字

    	Bar bar = new Bar(map.get(""+i), " 万元 " );

    	i++;

    	bar.setColour( "0x336699" ); // 颜色

    	bar.setTooltip(map.get(""+i) + " 万元 " ); // 鼠标移动上去后的提示

    	chart.addBars(bar); // 条标题,显示在 x 轴上

    	}



    	Chart flashChart = new Chart();          

    	flashChart.addElements(chart); // 把柱图加入到图表       

    	YAxis y = new YAxis(); //y 轴   

    	y.setMax(max+10.0); //y 轴最大值   

    	y.setSteps(max/10*1.0); // 步进   

    	flashChart.setYAxis(y); 

    	flashChart.setXAxis(x); 

    	String json = flashChart.toString();


    	response.setContentType( "application/json-rpc;charset=utf-8" );

    	response.setHeader( "Cache-Control" , "no-cache" );

    	response.setHeader( "Expires" , "0" );

    	response.setHeader( "Pragma" , "No-cache" );    

    	response.getWriter().print(json);// 写到客户端

    	return null;
    }
}


    其实,这个你在用ofc这个flex插件做图表时,你想啊,你得有数据吧,比如:饼图或者柱状图要显示的数据、x和y轴的标题、x和y轴每个分点代表什么之类,我以前用flex和java做时,需要将flex前端的所有信息在flex端组织成对象传给java端,java端在利用js解析这些对象的属性。但现在我们不用了,我们可以用别人直接封装好的类,利用类中的属性和方法直接将数据送给OFC。
     那么问题就来了,这个类是什么呢???你们可能也发现少了包的引用吧,嘿嘿~,我先把所有用到的包贴出来:
package snt.riskmanager.web.action.ofc_test2;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jofc2.model.Chart;
import jofc2.model.axis.XAxis;
import jofc2.model.axis.YAxis;
import jofc2.model.elements.BarChart;
import jofc2.model.elements.BarChart.Bar;
import jofc2.model.elements.PieChart;


import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import snt.riskmanager.web.action.BaseAction;

import com.thoughtworks.xstream.io.HierarchicalStreamDriver;

以snt开头的包,使我们公司自己的,我想你的公司肯定也有相同功能的东西吧~~
   
    (2).首先我们需要的jar包是:jofc2,我下载的名字是jofc2-1.0.0.jar,顾名思义:ofc的java实现,所以jofc,哈哈,我瞎理解的~
    一会儿去“附件”里找吧,jofc2-1.0-0.zip解压后就有那个jar包。
    
     有了上面这个jar包,当时我的情况是hello world打印,但是用来显示图表的区域还是什么都没有,还报错,我报的错但是没看懂,是关于这个东西的:com.thoughtworks.xstream.io.HierarchicalStreamDriver,好吧,果断没看过,我谷歌了一下,发现没有这个包xstream-1.3.1.jar,嘿嘿,我还是放在附件中,解压缩找找吧~~
    
    3.现在有了这些,我想你的图表应该出来了吧,如果还没出来,那么别着急,我们去检查下一下几点,主要是关于jsp页面中的内容: 
    (1).检查下面js文件的路径对不对
<script type="text/javascript" src="${ctxPath}/js/OFC/json2.js" charset="UTF-8"></script>
<script type="text/javascript" src="${ctxPath}/js/OFC/swfobject.js" charset="UTF-8"></script> 

    (2).检查对“open-flash-chart.swf”这个文件应用的路径对不对
swfobject.embedSWF(
		"${ctxPath}/jsp/ofc_test2/open-flash-chart.swf", 
		"my_piechart", 
		"40%", 
		"40%", 
		"10.0.0",
		"playerProductInstall.swf",
		{"data-file":"<%=request.getContextPath()%>/ofcTest2.do?cmd=toPieChart"},
		{wmode:"transparent"}
	);

      (3)备注:代码中的${ctxPath},你们不用纠结,其实你只要从项目名写到你文件所在的位置就行啦,这个解释也够直白吧~~,但要注意data-file这个属性的中action(.do)的写法以及不要忘了写cmd哦~~
  
      4.再次啰嗦几句吧,对于swfObject.embedSWF文件的理解,其实就是你要想在jsp和html中嵌入flex,就需要这个东西,我自己从网上找了资料汇总了下,请仔细看下面的解释:
      
  
//2.0  embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr, xiSwfUrlStr, flashvarsObj, parObj, attObj)
//2.2  embedSWF: function(swfUrlStr, replaceElemIdStr, widthStr, heightStr, swfVersionStr,xiSwfUrlStr, flashvarsObj, parObj, attObj, callbackFn) 
            
          //swfUrlStr(必须):swf位置 ;
            //replaceElemIdStr(必须):html中要替换成flash的元素的id
          //widthStr(必须):宽    
            //heightStr(必须):高
            //swfVersionStr(必须):flash版本
            
            //xiSwfUrlStr(可选):指定express install SWF的URL并激活Adobe express install
           //flashvarsObj(可选):用"name:value对"指定你的flashvars
           //parObj(可选):用"name:value对 "指定你的嵌套object元素的params(张熠的理解:指的是被用于"盛放"swf文件的那个元素的属性 )
           //attObj(可选):用"name:value对"指定object的属性(张熠的理解:指的是swf文件的属性)
            
           


    好了,我想说的就是这些了,当你看完这篇文章时,我相信你能用ofc展示饼图了,柱状图之类的你继续参照开头提到的文章将action中的实现写出来即可!
     该例子的不足就是action里的数据是直接写的,而不是从数据库抓出来的,不过这个实现起来很容易,我现在没时间,等过两天做报表时我会实现这个,到时再给大家补充一下。   
    
     不过,是否理解了,我想还是看每个人的主管能动性吧,我的出发点是那些基础不好或者懂得少但是真心想学的人,我相信这些人他们做完后会自己思考的~~
  
    最后,其实我就是这样的人,我以前专学c++,flex有基础,java会,但java应用会的太少,当时不会做就是希望有个人手把手教教我,因为有些东西即使我再和他较劲,没人提点我还是想不出来,所以我当时心里就一直在想,谁能教教我,说仔细些,从例子出发,我自己也一定会思考,不会照搬的.......哈哈,我觉得我还是很幸运的,公司的“老前辈”会不厌其烦的教我,默默感谢他们!!!希望大家一起学习,别人帮你是你的幸运,但我们要永远立足于自己学习,哈哈,这话说的够文艺吧~~

                   
           
          
   
        

你可能感兴趣的:(struts1)