Open Flash Chart使用簡記

來源:互聯網
上載者:User

對於Open Flash Chart(以下簡稱OFC)不再作過多介紹,很多網路部落格都對其作了相應介紹;這裡只是記錄一下自己最近幾天折騰OFC一些不常用特性的經過,以免以後再次忘記,權作學習筆記。

1、擷取OFC圖表對象

由於下面很多地方都用到了頁面嵌入的OFC對象,所以在此先定義一個擷取該對象的方法:

function findSWF(movieName) {      var movies = $("#" + movieName);      if(movies && movies.length && movies[0].tagName !== 'DIV') return movies[0];  } 

這裡的參數movieName其實就是載入OFC圖表SWF檔案時指定的ID;如果嵌入SWF檔案時沒有指定即embedSWF的最後一個參數裡沒有類似{id:'customID'}的代碼則預設會使用HTML元素的ID。

如下所示:

swfobject.embedSWF(flashPath, "chart", "100%", "100%", "9.0.0", "expressInstall.swf",{}, {},{id:'custom'});// ID為customswfobject.embedSWF(flashPath, "chart", "100%", "100%", "9.0.0", "expressInstall.swf",{}, {});// ID為chart
2、open_flash_chart_data()方法

OFC在頁面上被嵌入,如果沒有在嵌入SWF檔案時指定data-file,當頁面被訪問使其載入後,會調用該JavaScript方法來尋找圖表資料,所以我們可以在頁面上定義該方法,並在方法實現中創造(或者其它路徑,如向伺服器請求資料等)JSON資料,然後將JSON資料轉成String字串返回即可。OFC取得資料便可以渲染出相應的圖表內容。

樣本:

function open_flash_chart_data() {$.ajax({url: contextPath + '/ofc2/chart!barChart.action',type: 'post',data: {},dataType: 'json',success: function(data) {findSWF("chart").load(JSON.stringify(data));}});return "";}

上面這段代碼是在嵌入SWF後用AJAX方式去擷取資料,然後動態更新OFC圖表資料。因為資料是從伺服器擷取的而且AJAX是非同步,所以這個open_flash_chart_data方法無法直接返回JSON字串,而只能返回Null 字元串;在AJAX請求返回後才將資料傳遞給OFC。這其實並不實用,因為我們完全可以在嵌入SWF檔案時就指定URL,由OFC自己去請求資料,這樣還可以節省不少代碼,寫在這裡只是作為一個例子以助理解。

3、ofc_ready()方法

該回呼函數是在OFC載入資料之後調用的,在這個函數裡可以作一些操作,比如啟動一個計時器動態擷取最新資料,然後使頁面中的OFC動態載入最新資料,從而可以完成OFC的動態更新。

樣本:

/** * 在OFC載入完成資料之後,啟動定時器,2秒鐘更新一次圖表 */function ofc_ready() {setInterval(function () {update();}, 2000);}
4、OFC重新載入資料(圖表更新)

由於OFC圖表資料是在瀏覽器以JavaScript對象的形式進行持有(或者重新去伺服器端載入資料),所以非常容易對其進行操作,然後讓圖表Flash動態進行載入資料,從而可以對圖表動態更新。這裡利用了OFC圖表對象暴露的JavaScript回調介面load:

/**  * 操作資料代碼,依據個人需求修改資料或者重新擷取等  * 這裡的data參數是JSON對象,JSON.stringify方法是將其轉換為String串,方法定義在json2.js中  */  findSWF("chart").load(JSON.stringify(data)); 

這樣在資料正確的情況下,圖表就會重新渲染,完成動態更新。當然圖表的樣式可以隨意改變,不僅僅是圖表內容更新,比如,我們可以將餅圖變為線型圖,然後再變成直條圖,也可以將直條圖的資料改變一些之後再重新渲染成直條圖,只是柱子的高低有所變化;所以渲染成什麼樣子完全取決於資料。

5、圖表產生圖片

官網上說當我們需要將圖表儲存成圖片時有兩種選擇:
其一、產生圖片,然後上傳到伺服器儲存起來;
其二、產生圖片,然後傳給JavaScript函數;

5.1、上傳至伺服器

OFC暴露了一個介面用於將圖片資料上傳至伺服器,這就是post_image()方法;介面定義如下:

/** * @param url 是一個字串,即圖片上傳路徑,可以跟參數.如http://example.com/ofc/ofc_upload_img.php?name=chart.jpg * @param callback 字串類型,指定一個JavaScript方法名作為圖片上傳成功後的回呼函數,只有當debug參數為false時可用 * @param debug Boolean類型,如果為true會重新開啟一個視窗顯示結果 */post_image(url:String, callback:String, debug:Boolean);

比如我們可以這樣調用:

findSWF("chart").post_image(contextPath + "/ofc2/chart!postPicture.action?name=postImage",'',false);

當我們執行這句代碼時,OFC就會將圖片資料提交至我們給定的URL資源,這裡用的是Struts2的Action,但在Action如何接收資料我還不明確,官網上也沒有找到相關例子。

5.2、交給JavaScript處理

交給JavaScript處理的話可操作性就比較豐富了,我們可以將圖片直接顯示在當前頁面或者顯示在新視窗;也可以將圖片上傳至伺服器儲存;甚至類比圖片下載的方式由伺服器接收圖片資料後轉換成圖片再將檔案流寫回頁面等。不管採用何種操作,我們首先要做的就是擷取圖片資料,這裡又用到了OFC暴露的另外一個介面:get_img_binary(),這個方法用來擷取圖表對應圖片資料的Base64編碼。

比如我們可以將圖片資料直接傳給一個img元素,將其渲染到HTML頁面(IE7和IE7好像不支援base64編碼圖片顯示),如:

var base64Data = findSWF("chart").get_img_binary();  // 擷取圖表對應圖片資料的Base64編碼$("#showImg").empty().append("<img src='data:image/png;base64," + base64Data + "' />"); // 渲染一個圖片元素,添加到指定的DIV中

再比如我們將擷取到的Base64編碼提交給伺服器,伺服器進行解碼處理成圖片後再以檔案流方式寫回頁面,這樣就類似於圖片下載了:

/** * 這裡將圖片Base64編碼放進頁面的一個隱藏欄位,然後將該隱藏欄位所在的Form提交, * 這樣在伺服器寫出檔案流時會彈出檔案儲存對話方塊,也就類似於"圖片另存新檔..." */$("input[name='imgBase64Code']").val(findSWF("chart").get_img_binary());$("#savePicForm").submit();

5.3、伺服器接收圖片的Base64編碼資料

如果我們將圖片的Base64編碼提交提交到了伺服器,那麼為了得到未經處理資料我們需要在後台進行Base64解碼,然後將解碼後的資料輸出到瀏覽器實作類別似圖片下載的功能或者儲存下來;每種伺服器語言解碼方式可能都不一樣,在Java語言中可以使用Base64Decoder類來解碼。

樣本(採用Struts2的Action,參照網路例子):

public String savePicture() throws Exception {HttpServletRequest request = ServletActionContext.getRequest();HttpServletResponse response = ServletActionContext.getResponse();String imgBase64Code = request.getParameter("imgBase64Code");response.setContentType("image/PNG;charset=UTF-8");response.setHeader("Content-disposition", "attachment; filename=" + new String("flashExport.png".getBytes(), "iso-8859-1"));BASE64Decoder decoder = new BASE64Decoder();byte[] buffer = decoder.decodeBuffer(imgBase64Code);for (int i = 0; i < buffer.length; ++i) {             if (buffer[i] < 0) {             buffer[i] += 256;// 調整異常資料             }         }        response.getOutputStream().write(buffer);return null;}

6、Save_Image_Locally

OFC在Flash的右鍵菜單中預留了一個介面:Save_Image_Locally,這個功能表項目被點擊時會調用頁面中定義的名字為save_image的JavaScript方法。所以我們也可以將該介面作為上一步描述的JavaScript處理圖表產生的圖片資料的入口,比如我們定義如下的JavaScript方法:

// 點擊右鍵功能表項目中的“Save_Image_Locally”選項時觸發function save_image() {$("input[name='imgBase64Code']").val(findSWF("chart").get_img_binary());$("#savePicForm").submit();}

7、完整樣本

下面將一個完整樣本貼在此處,樣本中包含了上面描述的所有內容,例子並沒有將如何產生各種各樣的圖表作為重點,而主要測試的是OFC跟JS之間的互動。

7.1、:

                   

7.2、依賴的JS檔案

<script type="text/javascript" src="<%=path %>/js/jquery-1.7.2.min.js"></script><script type="text/javascript" src="<%=path %>/js/jquery-ui.min.js"></script><script type="text/javascript" src="<%=path %>/js/json2.js"></script><script type="text/javascript" src="<%=path %>/js/ofc2/swfobject.js"></script>

7.3、JSP頁面中HTML結構

<input type="hidden" id="contextPath" value="<%=request.getContextPath() %>" /><div><button onclick="chart()">載入圖表</button><button onclick="outputAsPicture()">輸出為圖片</button><button onclick="save_image()">儲存為圖片</button><button onclick="saveAsPicture()">儲存為圖片(post_image)</button><button onclick="updateChart()">更新圖表</button><div id="content" style="width: 540px;height: 360px;border: 2px solid red;"><div id="chart"></div></div><div id="showImg" style="width: 540px;height: 360px;border: 2px solid red;">圖片顯示於此</div></div><form action="<%=path %>/ofc2/chart!savePicture.action" id="savePicForm" method="post"><input type="hidden" name="imgBase64Code" /></form>

7.4、JavaScript實現

var contextPath;$(function (){contextPath = $("#contextPath").val();$("#content").resizable();})/** * 載入圖表 */function chart() {var flashPath = contextPath + "/js/ofc2/open-flash-chart.swf";var dataPath = contextPath + "/ofc2/chart!barChart.action";swfobject.embedSWF(flashPath, "chart", "100%", "100%", "9.0.0", "expressInstall.swf",{"data-file":dataPath}, {wmode:"transparent"});}/** * OFC擷取JSON資料方法 * @returns {String} JSON字串 */function open_flash_chart_data() {$.ajax({url: contextPath + '/ofc2/chart!barChart.action',type: 'post',data: {},dataType: 'json',success: function(data) {findSWF("chart").load(JSON.stringify(data));}});return "";}/** * 在OFC載入完成資料之後,啟動定時器,2秒鐘更新一次圖表 */function ofc_ready() {setInterval(function () {updateChart();}, 2000);}/** * 將圖表輸出為圖片,顯示在當前頁面的DIV元素中 */function outputAsPicture() {var base64Data = findSWF("chart").get_img_binary();$("#showImg").empty().append("<img src='data:image/png;base64," + base64Data + "' />");}/** * 使用OFC暴露的post_image介面向伺服器提交圖片資料 */function saveAsPicture() {findSWF("chart").post_image(contextPath + "/ofc2/chart!postPicture.action?name=postImage",'postDone',false);}/** * 使用OFC暴露的post_image介面向伺服器提交圖片資料成功後的響應函數 * @param id */function postDone(id) {alert('post image done!the id is ' + id);}/** * 動態更新圖表 */function updateChart() {var ofc = findSWF("chart");if(ofc) {$.ajax({url: contextPath + '/ofc2/chart!barChart.action',type: 'post',dataType: 'json',success: function(data) {ofc.load(JSON.stringify(data));}});}}/** * 利用隱藏欄位向伺服器提交圖片的Base64編碼資料,類比圖片另存新檔功能 */function save_image() {var base64Data = findSWF("chart").get_img_binary();$("input[name='imgBase64Code']").val(base64Data);$("#savePicForm").submit();}/** * 擷取OFC對象 * @param movieName 載入OFC時指定的id * @returns 指定的OFC */function findSWF(movieName) {var movies = $("#" + movieName);if(movies && movies.length && movies[0].tagName !== 'DIV') return movies[0];}

7.5、Struts2的Action實現

下面是伺服器代碼,採用Struts2的Action實現,依賴jofc2開源項目。實現了組裝OFC產生直條圖所需JSON資料及圖片下載等功能。類匯入部分省略。

package com.zyh.action.ofc2;// import code;public class ChartAction extends ActionSupport {private static final long serialVersionUID = 1L;/** * 產生直條圖,組裝OFC渲染直條圖所需資料  */public String barChart() {BarChart barChart = new BarChart(Style.GLASS);barChart.setText("Test Here");Random random = new Random();XAxis xAxis = new XAxis();xAxis.setColour("#909090");xAxis.setGridColour("#ADB5C7");int max = 0;for(int i = 0; i < 10; i++) {int temp = random.nextInt(100);if(max < temp) max = temp;Bar bar = new Bar(temp);barChart.addBars(bar);Label label = new Label("test" + temp);xAxis.addLabels(label);}YAxis yAxis = new YAxis();yAxis.setMax(max + 10);yAxis.setSteps(max / 10);Chart chart = new Chart("圖表測試", "{font-size: 20px; font-weight: bold; color: #A2ACBA; text-align: center;}");chart.addElements(barChart);Text xLegend = new Text("X軸圖例", "{font-size: 16px; font-weight: bold; color: #A2ACBA; text-align: center;}");chart.setXLegend(xLegend);Text yLegend = new Text("Number", "{font-size: 16px; font-weight: bold; color: #A2ACBA; text-align: center;}");chart.setYLegend(yLegend);chart.setXAxis(xAxis);chart.setYAxis(yAxis);try {System.out.println(chart.toString());writeChart(chart, ServletActionContext.getResponse());} catch (Exception e) {e.printStackTrace();}return null;}private void writeChart(Chart chart,HttpServletResponse response) throws Exception {response.setContentType("application/json-rpc;charset=utf-8");response.setHeader("Cache-Control", "no-cache");response.setHeader("Expires", "0");response.setHeader("Pragma", "No-cache");PrintWriter writer = response.getWriter();writer.write(chart.toString());writer.flush();writer.close();}/** * 該方法是響應OFC暴露的post_imgae()介面,但不知道如何取得圖片資料,暫時閑置 */public String postPicture() {HttpServletRequest request = ServletActionContext.getRequest();System.out.println(request.getParameter("name"));return null;}/** * 接收圖片Base64編碼,解壓後輸出至頁面,形成下載圖片效果  */public String savePicture() throws Exception {HttpServletRequest request = ServletActionContext.getRequest();HttpServletResponse response = ServletActionContext.getResponse();String imgBase64Code = request.getParameter("imgBase64Code"); response.setContentType("image/PNG;charset=UTF-8");     response.setHeader("Content-disposition", "attachment; filename=" + new String("flashExport.png".getBytes(), "iso-8859-1"));     BASE64Decoder decoder = new BASE64Decoder();     byte[] buffer = decoder.decodeBuffer(imgBase64Code);     for (int i = 0; i < buffer.length; ++i) {             if (buffer[i] < 0) {             buffer[i] += 256;// 調整異常資料             }         }response.getOutputStream().write(buffer);return null;}}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.