Open Flash Chart2 与1.x版本最大不同之处在于可以把数据格式改成JSON,可以很方便的运用Ajax实现动态加载数据,同时可以把生成的flash保存成图片(这个功能很实用)。
下面图文并茂一步一步详细介绍Open Flash Chart2的应用。
一、官网及相关下载的网站
- Open Flash Chart2 的官网:http://teethgrinder.co.uk/open-flash-chart-2/
- JOFC2:http://code.google.com/p/jofc2/
- http://sourceforge.net/projects/openflashchart/
本文附件将提供了一份已经整理好的demo源码下载:ofc2 demo源码。
二、HTML页面用JSON数据直接生成flash
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
<html> <head> <script type="text/javascript" src="ofc2/json2.js"></script> <script type="text/javascript" src="ofc2/swfobject.js"></script> </head> <body> <h2>页面直接生成flash</h2> <div id="my_chart"></div> </body> <script type="text/javascript"> swfobject.embedSWF("ofc2/open-flash-chart.swf", "my_chart", "400", "300", "9.0.0", "expressInstall.swf", {"get-data":"getDemoData"}); function getDemoData(){ var barData={ "y_axis":{"max":26,"steps":2.5}, "title":{"text":"每周水果产量"}, "is_decimal_separator_comma":0, "elements":[{"values":[ {"colour":"0x336699","tip":"16.0 吨 ","top":16}, {"colour":"0x336699","tip":"8.0 吨 ","top":8}, {"colour":"0x336699","tip":"18.0 吨 ","top":18}, {"colour":"0x336699","tip":"12.0 吨 ","top":12}, {"colour":"0x336699","tip":"16.0 吨 ","top":16}, {"colour":"0x336699","tip":"24.0 吨 ","top":24}, {"colour":"0x336699","tip":"6.0 吨 ","top":6} ], "type":"bar_glass"} ], "num_decimals":2, "is_fixed_num_decimals_forced":0, "x_axis":{"labels":{"labels":["星期1","星期2","星期3","星期4","星期5","星期6","星期日"]}}, "is_thousand_separator_disabled":0 }; return JSON.stringify(barData); } </script> </html> |
三、页面Ajax动态读取数据生成flash
java类中用到了jofc2-1.0-0.jar这个lib(包含于附件中)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
<%@ page language="java" contentType="text/html; charset=UTF-8"%> <html> <head> <link href="common/common.css" type="text/css" rel="stylesheet"> <script type="text/javascript" src="ofc2/swfobject.js"></script> </head> <body> <table width="100%"> <tr> <td> <h2>Ajax动态读取数据生成flash</h2> </td> </tr> <tr> <td> <div id="ofc2_bar01"></div> </td> </tr> </table> </body> <script type="text/javascript"> swfobject.embedSWF( "ofc2/open-flash-chart.swf", "ofc2_bar01", "400", "300", "9.0.0", "expressInstall.swf", {"data-file":"DrawOfc2ChartMainAction.do?method=getDrawBarData"}, {wmode:"transparent"} ); </script> </html> |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 |
/** * Open flash chart 2 * @author Michael sun */ public class DrawOfc2ChartMainAction extends DispatchAction { /** * draw chart * @param mapping struts mapping * @param form struts form * @param request http request * @param response http response * @return action forward * @throws Exception any execption */ public ActionForward getDrawBarData(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { response.setContentType("application/json"); response.setHeader("Cache-Control", "no-cache"); response.setCharacterEncoding("UTF-8"); PrintWriter out = response.getWriter(); Map<String, Double> dataMap = new LinkedHashMap<String, Double>(); dataMap.put("1", 16d); dataMap.put("2", 8d); dataMap.put("3", 18d); dataMap.put("4", 12d); dataMap.put("5", 16d); dataMap.put("6", 24d); dataMap.put("日", 6d); Chart ofc2Chart = new Chart(); Text title = new Text("每周水果产量"); ofc2Chart.setTitle(title); BarChart barChart = new BarChart(BarChart.Style.GLASS); // 设置条状图样式 double ymax = 25d; // //Y 轴最大值 XAxis x = new XAxis(); // X 轴 for (Entry<String, Double> entry : dataMap.entrySet()) { x.addLabels("星期" + entry.getKey()); // x 轴的文字 Bar bar = new Bar(entry.getValue(), " 吨 "); bar.setColour("0x336699"); // 颜色 bar.setTooltip(entry.getValue() + " 吨 "); // 鼠标移动上去后的提示 barChart.addBars(bar); // 条标题,显示在 x 轴上 } ofc2Chart.addElements(barChart); ofc2Chart.setXAxis(x); YAxis y = new YAxis(); // y 轴 y.setMax(ymax + 1.0); // y 轴最大值 y.setSteps(ymax / 10); // y 轴步进 ofc2Chart.setYAxis(y); String jsonChart = ofc2Chart.toString(); out.write(jsonChart); out.close(); return null; } } |
效果图如下:
下面介绍如何将生成的flash另存为图片,一般情况下我们运用js就可以直接在页面生产图片,
由于IE6、IE7 不支持base64编码图片显示,之后将介绍其他方法
当然不是必须要用这些JS库(jQuery 或prototype)才能完成这个功能,如果你不喜欢用这些JS库,也可以自己写的。
1.jQuery 的实现:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
<%@ page language="java" contentType="text/html; charset=UTF-8"%> <html> <head> <link href="common/common.css" type="text/css" rel="stylesheet"> <script type="text/javascript" src="common/jquery-1.3.2.js"></script> <script type="text/javascript" src="ofc2/swfobject.js"></script> </head> <body> <table width="900"> <tr> <td> <p>这是flash</p> <div id="ofc2_bar01"></div> </td> <td> <p>这是图片</p> <div id="img_chart_1"></div> </td> </tr> <tr> <td colspan="2"><input type="button" name="btncopy" onclick="OFC.jquery.rasterize('ofc2_bar01', 'img_chart_1')" value="生成图片"></td> </tr> </table> </body> <script type="text/javascript"> swfobject.embedSWF( "ofc2/open-flash-chart.swf", "ofc2_bar01", "300", "300", "10.0.0", "expressInstall.swf", {"data-file":"DrawOfc2ChartMainAction.do?method=getDrawBarData"}, {wmode:"transparent"} ); </script> <script type="text/javascript"> OFC = {}; OFC.jquery = { name: "jQuery", version: function(src) { return $('#'+ src)[0].get_version() }, rasterize: function (src, dst) { $('#'+ dst).replaceWith(OFC.jquery.image(src)) }, image: function(src) { return "<img src='data:image/png;base64," + $('#'+src)[0].get_img_binary() + "' />"}, popup: function(src) { var img_win = window.open('', 'Image') with(img_win.document) { write('<html><head><title>Charts: Export as Image</title></head><body>' + OFC.jquery.image(src) + '</body></html>') } // stop the 'loading...' message img_win.document.close(); } } // Using an object as namespaces is JS Best Practice. I like the Control.XXX style. //if (!Control) {var Control = {}} //if (typeof(Control == "undefined")) {var Control = {}} if (typeof(Control == "undefined")) {var Control = {OFC: OFC.jquery}} // By default, right-clicking on OFC and choosing "save image locally" calls this function. // You are free to change the code in OFC and call my wrapper (Control.OFC.your_favorite_save_method) // function save_image() { alert(1); Control.OFC.popup('my_chart') } function save_image() { alert(1); OFC.jquery.popup('ofc2_bar01') } function moo() { alert(99); }; </script> </html> |
点击页面上生成图片按钮后会在页面的右侧生成一张图片,如图:
把相应的JS和按钮的onclick 函数改写下就可以了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<script type="text/javascript"> OFC = {} OFC.prototype = { name: "Prototype", version: function(src) { return $(src).get_version() }, rasterize: function (src, dst) { $(dst).replace(new Element("img", {src: Control.OFC.image(src)})) }, image: function(src) {return "data:image/png;base64," + $(src).get_img_binary()}, popup: function(src) { var img_win = window.open('', 'Image') with(img_win.document) { write("<html><head><title>Charts: Export as Image</title></head><body><img src='" + Control.OFC.image(src) + "' /></body></html>") } } } // Using an object as namespaces is JS Best Practice. I like the Control.XXX style. if (typeof(Control == "undefined")) {var Control = {OFC: OFC.prototype}} //if (!Control) {var Control = {}} // By default, right-clicking on OFC and choosing "save image locally" calls this function. // You are free to change the code in OFC and call my wrapper (Control.OFC.your_favorite_save_method) function save_image() { Control.OFC.popup('ofc2_bar01') } </script> |
3.不要任何JS库
只要把相应的JS和按钮的onclick 函数改写下就可以了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<script type="text/javascript"> OFC = {} OFC.none = { name: "pure DOM", version: function(src) { return document.getElementById(src).get_version() }, rasterize: function (src, dst) { var _dst = document.getElementById(dst) e = document.createElement("div") e.innerHTML = Control.OFC.image(src) _dst.parentNode.replaceChild(e, _dst); }, image: function(src) {return "<img src='data:image/png;base64," + document.getElementById(src).get_img_binary() + "' />"}, popup: function(src) { var img_win = window.open('', 'Image') with(img_win.document) { write("<html><head><title>Charts: Export as Image</title></head><body>" + Control.OFC.image(src) + "</body></html>") } } } if (typeof(Control == "undefined")) {var Control = {OFC: OFC.none}} function save_image() { Control.OFC.popup('ofc2_bar01') } </script> |
另打开页面显示图片:在生成flash右击,选中Save Image locally 如下图:
由于IE6、IE7不支持base64码,如果要在IE6、IE7中兼容,可以将图片的base64码post到服务器,然后利用服务端生成图片,再将文件流在返回给浏览器(类似图片下载的方法),具体如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
/** * upload img * @param mapping struts mapping * @param form struts form * @param request http request * @param response http response * @return action forward * @throws Exception any execption */ public ActionForward exportImg(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { 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")); this.createImg(response.getOutputStream(), imgBase64Code); return null; } /** * * @param os * @param base64Code */ private void createImg(OutputStream os, String base64Code) { BASE64Decoder decoder = new BASE64Decoder(); try { byte[] b = decoder.decodeBuffer(base64Code); for (int i = 0; i < b.length; ++i) { if (b[i] < 0) { b[i] += 256; } } os.write(b); } catch (Exception e) { logger.error(" create img error:", e); } } |
原创文章,转载请注明: 转载自micmiu – 软件开发+生活点滴[ http://www.micmiu.com/ ]
楼主 你好 我复制您的代码
也一直在loading data。。。。
请问这是什么原因?如何解决啊?
你把页面放在web容器中运行再试试