这两天学习了 Open Flash Chart 。写了一个简单的 Hello World 程序,给大家分享一下
1, Open Flash Chart(OFC) 介绍
OFC 使用 Flash 来展现图表,包括直线图、素描图、柱状图和饼图等,具有生动美观的特点。目前 OFC 已经升级到 2.0 版本(地址: http://teethgrinder.co.uk/open-flash-chart-2/ ), 1.x 版本(地址: http://teethgrinder.co.uk/open-flash-chart/index.php )已经停止支持,但仍然普遍使用。在这里我使用的是 Open Flash Chart 2 。 2 版源码经过了优化,使用了 ActionScript 3 ,并且用 Adobe Flex 来编译。当然,最重要的改变还是对 JSON 格式数据源的支持!
2 , OFC 图表生成原理
简单来说,生成 OFC 图表的需要2样东西, 1 是 open-flash-chart.swf Flash 文件,用于绘制图表。 2 是 JSON 数据源。我们可以在 Web 或 RCP 中加载 Flash 文件,然后读取 JSON 数据来展现图表。
3 , OFC 的编程实现
目前 PHP , Python , Ruby , .NET , JAVA 等已经有 OFC 的实现。这里只介绍 JAVA 的实现。
1 )首先下载 OFC2 ,下载地址 http://teethgrinder.co.uk/open-flash-chart-2/downloads.php ,这里使用的是 Version 2 Lug Wyrm Charmer (28th, July 2009) 版。下载完成之后解压,拷贝 open-flash-chart-2-Lug-Wyrm-Charmer\js\swfobject.js 和 open-flash-chart-2-Lug-Wyrm-Charmer\open-flash-chart.swf 两个文件到 Web 项目中。其中, swfobject.js 是操作 flash 的脚本文件, open-flash-chart.swf 前面已经介绍过了。
2 )另外一个必需的东西是 JSON 数据源,这里写了一个专门获取 JSON 数据源的 Servlet 类: GetJsonServlet
package com.test.servlet; import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import jofc2.model.Chart; import jofc2.model.axis.Label; import jofc2.model.axis.XAxis; import jofc2.model.axis.YAxis; import jofc2.model.elements.BarChart; import jofc2.model.elements.BarChart.Bar; /** * Servlet implementation class GetJsonServlet */ public class GetJsonServlet extends HttpServlet { private static final long serialVersionUID = 1L; /** * Default constructor. */ public GetJsonServlet() { // TODO Auto-generated constructor stub } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<MonitorCount> counts = initDatas(); int total = counts.size(); List<Label> xLabels = new ArrayList<Label>(total); List<Bar> barList = new ArrayList<Bar>(total); for(int i=0; i<total; i++) { MonitorCount mCount = counts.get(i); int count = mCount.getCount(); barList.add(new Bar(count)); String xLabel = mCount.getLabel(); xLabels.add(new Label(xLabel)); } // 设置X轴坐标值 XAxis xAxis = new XAxis(); xAxis.addLabels(xLabels); // 设置Y轴的范围 YAxis yAxis = new YAxis(); yAxis.setRange(0, 150, 10); BarChart barChart = new BarChart(BarChart.Style.GLASS); barChart.addBars(barList); barChart.setText("HTTP BarChart"); Chart chart = new Chart("HTTP日访问量"); chart.setXAxis(xAxis); chart.setYAxis(yAxis); chart.addElements(barChart); String json = chart.toString(); System.out.println("json = " + json); sendJson(response, json); } /** * 模拟初始化数据 * @return */ private List<MonitorCount> initDatas() { List<MonitorCount> data = new ArrayList<MonitorCount>(); data.add(new MonitorCount("1月", 100)); data.add(new MonitorCount("2月", 120)); data.add(new MonitorCount("3月", 140)); data.add(new MonitorCount("4月", 125)); data.add(new MonitorCount("5月", 145)); data.add(new MonitorCount("6月", 138)); return data; } /** * 返回JSON数据给客户端 * @param response * @param json */ protected void sendJson(HttpServletResponse response, String json) { response.setContentType("application/json; charset=utf-8"); PrintWriter writer = null; try { writer = response.getWriter(); writer.write(json); } catch (IOException e) { e.printStackTrace(); } finally { if (null != writer) { writer.flush(); writer.close(); } } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this.doGet(request, response); } } class MonitorCount { private String label; private Integer count; public MonitorCount(String label, Integer count) { super(); this.label = label; this.count = count; } public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } }
类中用到了 jofc2 ( Java API for Open Flash Chart 2 , 地址: http://code.google.com/p/jofc2/ )的两个 jar 包, jofc2-1.0-0.jar 和 xstream-1.3.1.jar 。
3 )访问页面 index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Open Flash Chart - Hello World</title> <script type="text/javascript" src="swfobject.js"></script> <script type="text/javascript"> var url = encodeURIComponent("/OpenFlashChartHelloWorld/GetJsonServlet"); swfobject.embedSWF("open-flash-chart.swf", "chart", "950", "500", "9.0.0", "expressInstall.swf",{"data-file":url}); </script> </head> <body> <div id="chart"></div> </body> </html>
4 )运行程序之后页面的显示效果图
如果看到这个结果: C:\Users\John\Documents\flash\svn\data-files\data-47.txt
则可能是 open-flash-chart.swf 文件是 OFC 1.x 版本的,把它换成 2 版本的就成了。
4 ,总结
Open Flash Chart 除了可以显示多种图表外,还提供了一些强大的功能,比如高亮、突出某个点,将图表保存成图片,在图表中移动鼠标会有提示信息,点击图表响应事件等。在项目开发过程中我们经常需要根据实现情况调整数据的来源或者显示的图形。这里我只是写一个简单的入门程序,有兴趣的童鞋可以自己去阅读官方网站或查阅相关的文档。
附:本例源码。