通过使用richfaces 3.3对FusionCharts V3产生的图表自动进行刷新。内容刷新,不是整个swf区域刷新

在jsf中,我通过FusionChartsV3来产生图表。同时使用了jsf的push技术,来自动更新图表的数据。

利用到的组件有

  • <a4j:push>
  • FusionCharts

主界面的xhtml和显示图表的xhtml界面如下:

  • index.xtml
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:rich="http://richfaces.org/rich" xmlns:a4j="http://richfaces.org/a4j"> <body> <ui:composition> <mce:script language="JavaScript" src="./FusionCharts/FusionCharts.js" mce_src="FusionCharts/FusionCharts.js"></mce:script> <mce:script type="text/javascript"><!-- var myTypeFChart; var myTypeSChart; var myTypeJChart; //重画所有图表 function redrawAllCharts(chartObjectList,chartDataList){ var chartObj; var i=0; console.debug(i); console.debug( chartDataList.length); console.debug(i &lt; chartObjectList.length); for (i=0 ; i &lt; chartObjectList.length ; i++) { console.debug("正在重画的swf ID是:"+chartObjectList[i]+",内容是:"+chartDataList[i]); console.debug("重画开始"); chartObj = getChartFromId(chartObjectList[i]); chartObj.setDataXML(chartDataList[i]); console.debug("重画结束"); } } // --></mce:script> <link href="./css/projectMain.css" mce_href="css/projectMain.css" rel="stylesheet" type="text/css" /> <h:form> <a4j:push interval="5000" eventProducer="#{overallIndexView.addListener}" enabled="true" id="push" reRender="push,tableF,tableS,tableJ" oncomplete='redrawAllCharts( ["chartSwfTypeF","chartSwfTypeS","chartSwfTypeJ"], ["#{overallIndexView.overallIndexTypeFCharData}","#{overallIndexView.overallIndexTypeSCharData}","#{overallIndexView.overallIndexTypeJCharData}"])' /> <rich:panel style="border:0px;padding:0px" mce_style="border:0px;padding:0px" bodyClass="rich-laguna-panel-no-header"> <!-- <h1 align="center"><h:outputText value="杭州市道路交通总体运行状况" /></h1>--> <!-- 全部区域显示图表--> <h:panelGrid columns="3" columnClasses="gridContent" width="screen.width/3"> <rich:panel bodyClass="rich-laguna-panel-no-header" styleClass="fullScreen"> <!-- 各等级道路断面平均流量时变图--> <ui:include src="./chart/chartTypeF.xhtml" mce_src="chart/chartTypeF.xhtml" /> </rich:panel> <rich:panel bodyClass="rich-laguna-panel-no-header" styleClass="fullScreen"> <!--各等级道路平均行程车速时变图--> <ui:include src="./chart/chartTypeS.xhtml" mce_src="chart/chartTypeS.xhtml" /> </rich:panel> <rich:panel bodyClass="rich-laguna-panel-no-header" styleClass="fullScreen"> <!--各等级道路拥堵里程比例时变图--> <ui:include src="./chart/chartTypeJ.xhtml" mce_src="chart/chartTypeJ.xhtml" /> </rich:panel> </h:panelGrid> </ui:composition> </body> </html>  
  • 图表的xhtml
    <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:rich="http://richfaces.org/rich" xmlns:a4j="http://richfaces.org/a4j"> <rich:panel id="chartTypeF" bodyClass="inpanelBody fullScreen" styleClass="fullScreen"> <div id="myMSLineChartTypeFDiv" align="center" class="noborder" /> <mce:script type="text/javascript"><!-- myTypeFChart = new FusionCharts("./FusionCharts/MSLine.swf","chartSwfTypeF", "330", "300", "0", "1"); myTypeFChart.setDataXML("#{overallIndexView.overallIndexTypeFCharData}"); myTypeFChart.render("myMSLineChartTypeFDiv"); // --></mce:script> </rich:panel> </ui:composition>

需要注意的有以下几点

  1. 总体思路是:通过push机制。在后台数据有回调的情况下。使用了a4j:push 的oncomplete属性调用一个javascript方法,并且把后台bean的内容(画图表所需要的data xml字符串)作为参数赋值传递个这个方法。这个方法去调用FushionCharts的js刷新方法去重绘图表。经过测试不能直接在js的方法中使用后台bean的el表达式。否则后台数据变化后,前台js方法不会得到新的值。可能是因为a4j:push无法去让js方法刷新的原因。
  2. 另外一种思路是,通过a4j:push的reRender属性。去刷新整个包含图表的<rich:panel>区域。也可以刷新。但是这个方法会导致整个swf重新载入,显示效果相当不理想。
  3. function redrawAllCharts()这个函数一定要定义在主程序的js区域。不能定义在各个图表的xhtml里面。否则在运行到 chartObj = getChartFromId(chartObjectList[i]);这个方法的时候。会拿不到 chartSWF的对象。在FF下调试会出现一个warning。说需要使用document.getElementByID方法来获得对象。显而易见,利用这个函数是无法获得fushionCharts特定对象的。
  4.  chartObj = getChartFromId(chartObjectList[i]); 这个方法中的参数,应该和图表的xhtml中语句myTypeFChart = new FusionCharts("./FusionCharts/MSLine.swf","chartSwfTypeF", "330", "300", "0", "1"); 中的 "chartSwfTypeF"变量相对应。而不是div的id。
  5. myTypeFChart.render("myMSLineChartTypeFDiv");render的参数应该是需要画图表的div的ID。
  6. new FusionCharts("./FusionCharts/MSLine.swf","chartSwfTypeF", "330", "300", "0", "1");倒数第二个参数表示图表是否显示debug模式。最后一个参数表示一定要设置成1,不能用缺省值0.否则不会刷新
    官方有关这个参数的说明如下:
    Registering with JavaScript and tracking the rendered event
    For this example, create a simple HTML page BasicExample.html with the following code:
    <HTML>
    <HEAD>
       <TITLE>FusionCharts & JavaScript - Basic Example</TITLE>
       <SCRIPT LANGUAGE="Javascript" SRC="../../FusionCharts/FusionCharts.js"></SCRIPT>
       <SCRIPT LANGUAGE="JavaScript">
          //FC_Rendered method is called whenever a FusionCharts chart on the page
          //has finished initial rendering. To this function, the chart passes its
          //own DOM Id.

          function FC_Rendered(DOMId){
             //If it's our required chart
             if (DOMId=="chart1Id"){
                //Simply alert
                window.alert("Look Ma! I am Column3D and I've finished loading and rendering.");
                return;
             }
          }
       </SCRIPT>
    </HEAD>
    <BODY>
       <div id="chart1div">
          FusionCharts
       </div>
       <script language="JavaScript">
          var chart1 = new FusionCharts("../../FusionCharts/Column3D.swf", "chart1Id ", "400", "300", "0", "1" );
          chart1.setDataXML("<chart><set label='A' value='10' /><set label='B' value='11' /></chart>");
          chart1.render("chart1div");
       </script>
    </BODY>
    </HTML>

    In the above code, we are first creating a Column3D chart using FusionCharts JavaScript class. We set the DOM Id of the chart as chart1Id . It is this ID using which the chart will now be recognized in the HTML page. You need to make sure that each chart on the page gets a different Id, else the browser would start behaving weirdly.

    To register the chart with JavaScript, we set the registerWithJS parameter to 1. It's the last parameter in FusionCharts constructor function.

    var chart1 = new FusionCharts("../../FusionCharts/Column3D.swf", "chart1Id", "400", "300", "0", "1" );

    Now, we've provided a basic XML data document to chart using its setDataXML method. Finally, we render the chart.

    If you now switch to <SCRIPTS> section of HTML <HEAD> , you'll find the following function:

    <SCRIPT LANGUAGE="JavaScript">
       //FC_Rendered method is called whenever a FusionCharts chart on the page
       //has finished initial rendering. To this function, the chart passes its
       //own DOM Id.

       function FC_Rendered(DOMId){
          //If it's our required chart
          if (DOMId=="chart1Id"){
             //Simply alert
             window.alert("Look Ma! I am Column3D and I've finished loading and rendering.");
             return;
          }
       }
    </SCRIPT>

    The above function FC_Rendered() gets invoked whenever a FusionCharts chart (on the page) has finished rendering for the first time. To this function, the chart passes its own DOM Id, so that we can cross refer to it.

    In our example, when the Column 3D chart (with DOM Id chart1ID ) has finished rendering, it calls this function too. In this function, we check if it was invoked by our required Column 3D chart. To do so, we match the DOM Id passed to this id with the DOM Id of our Column chart. This is useful when you've multiple charts on page and you want to track loading of each of those charts.

    Finally, in this function, we output a message to the user that the chart has been loaded. In your applications, you can put in application logic here (or AJAX code) to get data or build data and then update the chart, which we'll soon see.

    Now that you're famililar with the basic concepts of FusionCharts and JavaScript, we'll next see how to change the data of a chart at client side using setDataXML method.

你可能感兴趣的:(JavaScript,XHTML,function,Richfaces,include,stylesheet)