JS Chart與JSF交互的方法

最近用JSF做項目,其中有很多圖表要繪製,而JSF框架自帶的製圖插件太雞肋了,不得不使用強大的JS製圖插件。可是怎麼交互數據實在是腦疼的事情。js請求JSF後臺managed bean是個很糾結的問題,不像請求servlet一樣。本人想到三種方法:

第一種就是利用jsf.js(這是jsf核心庫裏面的js函數),這個裏面的mojarra.ab(s, e, n, ex, re, op)方法,其實就是jsf.ajax.request(s, e, op)方法,s是請求源的id,e是事件類型,op是一組請求的屬性,例如jsf.ajax.request("testform:test", event, { execute: 'testform:test', render: 'testform:testValue'})使用這種方法必須要現在jsf頁面中先有一個存值的jsf標籤,下面的代碼對應上面請求的頁面代碼。

            <h:form id="testform">
                <h:commandButton styleClass="cbutton" value="測試" id="test" action="#{userLogin.testAction()}"/>
                <h:outputText id="testValue" styleClass="testvalue" value="#{userLogin.i}"/>
            </h:form>

而value="#{userLogin.i}"中的i就是我要請求的值。如果用jquery來對一個一個div(id="test")標籤賦值,js寫法如下:

<script>

                $(function(){
                    jsf.ajax.request("testform:test", event, { execute: 'testform:test', render: 'testform:testValue'});
                    $("div#test").val($(".testvalue").val());
                });
</script>
看上去這種方法很笨重,但是這也是沒辦法的事情。


第二種其實是一個折中的方法,現在後臺managed bean中生成數據,儲存在制定的文件裏面,然後前臺用ajax請求數據的地址。我現在就用的這種方法,重點講一下這個實現方法:

我需要用一個叫highcharts的製圖插件,具體用法不說了,貼一點代碼上來再解釋一下:

首先是js代碼

<script type="text/javascript">
                    Highcharts.setOptions({
                        global: {
                                useUTC: true
                        }
                    });
                    var chart;
                    jQuery(document).ready(function() {
                        function getRootPath(){
                            var strFullPath=window.document.location.href;
                            var strPath=window.document.location.pathname;
                            var pos=strFullPath.indexOf(strPath);
                            var prePath=strFullPath.substring(0,pos);
                            var postPath=strPath.substring(0,strPath.substr(1).indexOf('/')+1);
                            return(prePath+postPath);
                        } 

                        var options = {
                                chart: {
                                        renderTo: 'errorstatisticcontainer',
                                        defaultSeriesType: 'spline',
                                        marginRight: 10,
                                        zoomType: 'xy'
                                },
                                title: {
                                        text: '\u529f率對比圖'
                                },
                                xAxis: {
                                        type: 'datetime',
                                        tickPixelInterval: 150
                                },
                                yAxis: {
                                        title: {
                                                text: '\u529f率'
                                        },
                                        plotLines: [{
                                                value: 0,
                                                width: 1,
                                                color: '#808080'
                                        }]
                                },
                                tooltip: {
                                        crosshairs: [{
                                            width: 1
                                        }, {
                                            width: 1
                                        }],
                                        shared: true
                                },
                                legend: {
                                        enabled: true
                                },
                                exporting: {
                                        enabled: true
                                },
                                plotOptions: {
                                        spline: {
                                                marker: {
                                                        radius: 5,
                                                        lineWidth: 1
                                                }
                                        }
                                },
                                series: [{
                                        name: '\u5b9e發功率',
                                        lineWidth: 2,
                                        marker: {
                                            symbol: 'circle',
                                            radius: 2
                                        }
                                }, {
                                        name: '\u9884測功率',
                                        lineWidth: 2,
                                        marker: {
                                            symbol: 'triangle',
                                            radius: 2
                                        }
                                }]
                        };

                        var url = getRootPath()+'/resources/json/temp.json';
                        jQuery.getJSON(url,function(json, state, xhr){
                            var rdata = [];
                            var fdata = [];
                            var _data = json.data;
                            jQuery.each(_data,function(i){
                                rdata.push([
                                    _data[i].time, _data[i].r
                                ]);
                                fdata.push([
                                    _data[i].time, _data[i].f
                                ]);
                            })
                            options.series[0].data = rdata;
                            options.series[1].data = fdata;
                            chart = new Highcharts.Chart(options);
                        })
                    })
                </script>

這裏面有三個部分,第一個是繪製圖表。第二個就是獲取URL,獲取URL的方法就是getRootPath(),然後加上"/resources/json/temp.json",後面的這個字符串是後臺指定的。第三部分就是獲取數據了,這裏用到的是jQuery.getJSON()方法了。

除了上面的js,還需要一個div來繪製圖表,這個很簡單,一句話(其中errorstatisticcontainer對應js中renderTo屬性值):

<div id="errorstatisticcontainer" style="width: 1000px; height: 600px; margin: 0 auto"></div>

再者就是managedbean的方法了

    private static String path = "resources\\json\\temp.json";
   //把json格式的字符串寫到文件
    public static void writeFile(String filePath, String sets) {
        FileWriter fw = null;
        try {
            fw = new FileWriter(filePath);
            PrintWriter out = new PrintWriter(fw);
            out.write(sets);
            out.println();
            fw.close();
            out.close();
        } catch (IOException ex) {
            Logger.getLogger(ErrorStatisBean.class.getName()).log(Level.SEVERE, null, ex);
        } finally {
            try {
                fw.close();
            } catch (IOException ex) {
                Logger.getLogger(ErrorStatisBean.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }
    
    public void setDataAction(){
        //獲取json路徑
        FacesContext context = FacesContext.getCurrentInstance();
        ServletContext servletContext = (ServletContext) context.getExternalContext().getContext();
        String rootPath = servletContext.getContextPath();
        String _rootPath = servletContext.getRealPath("/");
        String filepath = _rootPath + path;
        JSONObject jsonObj = new JSONObject();
            for (long time = starttime; time <= endtime; time += timestep) {
                try {
                    Object f = fMap.get(time);
                    Object r = rMap.get(time);
                    Map<String, Object> data = new HashMap<String, Object>();
                    data.put("time", time);
                    data.put("r", r);
                    data.put("f", f);
                    jsonObj.append("data", data);
                } catch (JSONException ex) {
                    Logger.getLogger(ErrorStatisServiceImpl.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        writeFile(filepath,jsonObj );
    }

這樣就可以出現數據,發張截圖如下:


還有低三種方法:就是另寫一個jsp,在jsp中請求調用jsf後臺的方法,這個看起來有點不倫不類,而且有參數的時候需要把參數值放入到session中,其實增加了一些麻煩!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章