使用Open Flash Chart(OFC)制作图表(Struts2处理)-程序员宅基地

技术标签: ViewUI  json  sketch  javascript  

Java开源项目中制作图表比较出色的就是JFreeChart了,相信大家都听说过,它不仅可以做出非常漂亮的柱状图,饼状图,折线图基本图形之外,还能制作甘特图,仪表盘等图表。在Web应用中可以为项目增色不少。JFreeChart技术成熟,完全是通过Java代码控制图表生成,掌握难度不大。但是它的一个缺点就是所有资源在服务器端生成,需要占用大量的服务器资源,而且图表以流的形式输送到客户端也占用了大量的网络资源。 
    对于服务器资源和网络资源吃紧的项目还不得不想办法,虽然JFreeChart非常的华丽,但是还好有Open Flash Chart,制作简单的柱状图,饼状图和折线图足够用,而且Flash的展示效果绝不比JFreeChart的差。项目地址是:http://teethgrinder.co.uk/open-flash-chart/ 
    先说说Open Flash Chart的工作原理,不要看到Flash就害怕,OFC的开发包内就是一个flash文件,其实我们不需要改动原有的Flash,只需给Flash提供符合规范的数据即可。OFC所需的数据格式就是JSON,JSON不依赖于任何技术(Java,.NET和PHP都有生成JSON代码的工具),这就使得OFC更加Open。本文从Java角度出发,使用Struts2框架,来分析OFC的使用。 
    GoogleCode社区的一款开源插件为Java开发者使用OFC提供了JSON生成的专用工具,那就是jofc2,我可以使用jofc2采用类似JFreeChart的方式来组织代码,大大提升开发效率。该项目的地址是:http://jofc2.googlecode.com 
    项目按照Struts2的开发标准搭建,然后把OFC开发所需的flash文件,页面显示Flash的支持文件swfobject.js放到发布目录的相应位置,再将jofc2和其依赖的xstream的jar包放到WEB-INF/lib下并加入编译路径即可。 
    有这样一个需求:记录系统访问用户所使用的浏览器并用图表显示。那么需要在数据库中记录这样的信息,如图所示: 
 
    这里面记录了9种浏览器的系统访问量,现在我们要在页面中用OFC来显示它,首先对Struts2做配置。代码如下: 
Java代码   收藏代码
  1. package xxx.app.action.chart;  
  2. import java.util.ArrayList;  
  3. import java.util.List;  
  4. import java.util.Map;  
  5. import javax.servlet.http.HttpServletResponse;  
  6. import org.apache.struts2.ServletActionContext;  
  7. import jofc2.model.Chart;  
  8. import jofc2.model.axis.Label;  
  9. import jofc2.model.axis.XAxis;  
  10. import jofc2.model.axis.YAxis;  
  11. import jofc2.model.elements.LineChart;  
  12. import xxx.app.action.BaseAction;  
  13. public class OfcChartAction extends BaseAction {  
  14.     private Chart ofcChart;  
  15.     public Chart getOfcChart() {  
  16.         return ofcChart;  
  17.     }  
  18.     public String showChart() throws Exception{  
  19.         //y轴数据集合-使用数量  
  20.         List<Number> dataSet = new ArrayList<Number>();  
  21.         //x轴数据集合-浏览器类型  
  22.         List<Label> xLabel = new ArrayList<Label>();  
  23.         //获取需要显示的数据集  
  24.         List browserList = getServMgr().getVisitStatService().getBrowserStat();  
  25.         for (int i = 0; i < browserList.size(); i++) {  
  26.             Map map = (Map) browserList.get(i);  
  27.             //填充x轴  
  28.             dataSet.add((Integer) map.get("statCount"));  
  29.             //填充y轴  
  30.             xLabel.add(new Label((String) map.get("statVar")));  
  31.         }  
  32.         //设置X轴内容  
  33.         XAxis labels = new XAxis();  
  34.         labels.addLabels(xLabel);  
  35.         //设置Y轴显示值域:Range的三个参数含义为:坐标最小值,最大值和步进值  
  36.         YAxis range = new YAxis();  
  37.         range.setRange(0, 200, 10);  
  38.         //OFC折线图设置  
  39.         LineChart lineChart = new LineChart(LineChart.Style.NORMAL);  
  40.         lineChart.addValues(dataSet);  
  41.         lineChart.setColour("#6666FF");  
  42.         lineChart.setText("使用者数量");  
  43.         //图表设置  
  44.         Chart chart = new Chart("用户浏览器使用量分布");  
  45.         chart.setXAxis(labels);  
  46.         chart.setYAxis(range);  
  47.         chart.addElements(lineChart);  
  48.         //打印JSON格式的文本  
  49.         System.out.print(chart.toString());  
  50.         HttpServletResponse response = ServletActionContext.getResponse();  
  51.         response.setContentType("application/json-rpc;charset=utf-8");  
  52.         response.setHeader("Cache-Control", "no-cache");  
  53.         response.setHeader("Expires", "0");  
  54.         response.setHeader("Pragma", "No-cache");  
  55.         response.getWriter().write(chart.toString());  
  56.         return null;  
  57.     }  
  58. }  

    Service中获取数据我们使用Spring的JdbcTemplate进行。 
Java代码   收藏代码
  1.     //获取记录的浏览器信息  
  2. private static final String SQL_GET_BROWER_STAT = "select statVar,statCount from nd_stats where statType='browser'";  
  3. /** 
  4.  * 获取记录的浏览器信息 
  5.  */  
  6. public List getBrowserStat() {  
  7.     return jt.queryForList(SQL_GET_BROWER_STAT);  
  8. }  

    写好Action,我们简单配置一下,因为我们只是得到JSON文本,所以不必配置跳转,只需配置请求即可。 
Xml代码   收藏代码
  1. <action name="ofcChart" class="xxx.app.action.chart.OfcChartAction">  
  2. </action>  

    页面的JS代码也很简单。如下即可: 
Html代码   收藏代码
  1. <script type="text/javascript" src="${base}/js/swfobject.js"></script>  
  2. <script type="text/javascript">  
  3.     var flashvars = {"data-file":"${base}/manage/stat/ofcChart!showChart.action"};  
  4.     var params = {menu: "false",scale: "noScale",wmode:"opaque"};  
  5.     swfobject.embedSWF("${base}/swf/open-flash-chart.swf", "chart", "600px", "400px", "9.0.0",  
  6.     "expressInstall.swf",flashvars,params);  
  7. </script>  
  8. <div id="chart">  
  9. </div>  

    这里需要多说几句,首先是路径,不能错了,错了就请求不到数据了。Swfobject.js是页面使用JS方式配置Flash显示的,比较方便,所有使用它了。设置一个div用于Flash的显示,这个id是embedSWF的第二个参数,不能忘写了。还有就是请求地址参数的问题,这里我们是方便测试就没有传递参数,而实际开发不可避免传递参数。参数传递时在请求地址后面按普通形式书写即可,只是&这个连接符需要转义,写成%26,其他就没有什么了。 
    我们得到的结果就是这样的,这是很普通的折线图。但是不比JFreeChart的差哦。 
 
    同时在控制台我们得到jofc2为我们生成的JSON文本。 
Js代码   收藏代码
  1. { "is_thousand_separator_disabled":0,"is_decimal_separator_comma":0,"title":{"tex  
  2. t":"用户浏览器使用量分布"},"y_axis":{"min":0,"steps":10,"max":200},"x_axis":{"la  
  3. bels":{"labels":[{"text":"Safari"},{"text":"MSIE6X"},{"text":"MSIE7X"},{"text":"  
  4. MSIE8X"},{"text":"Firefox"},{"text":"Chrome"},{"text":"Opera"},{"text":"Maxthon"  
  5. },{ "text":"Other"}]}},"num_decimals":2,"is_fixed_num_decimals_forced":0,"element  
  6. s":[{"font-size":10,"text":"使用者数量","type":"line","values":[6,2,63,168,1,10,  
  7. 1,0,0],"colour":"#6666FF"}]}  

    下面我们做柱状图,做个个性点的,用sketch类型。 
Java代码   收藏代码
  1. //Sketch型柱状图设置  
  2. SketchBarChart sketchChart = new SketchBarChart();  
  3. sketchChart.setColour("#6666FF");  
  4. sketchChart.addValues(dataSet);  
  5. sketchChart.setText("使用者数量");  
  6. //图表设置  
  7. Chart chart = new Chart("用户浏览器使用量分布");  
  8. chart.setXAxis(labels);  
  9. chart.setYAxis(range);  
  10. chart.addElements(sketchChart);  

    这样我们就得到了下面的显示效果,是不是很卡通,哈哈。 
 
    需要注意jofc2将sketch风格的柱状图单独写成了一个类,而使用普通风格的柱状图时不时这么进行的。 
Java代码   收藏代码
  1. //柱状图Bar的集合  
  2. List<Bar> barList=new ArrayList<Bar>();  
  3. for (int i = 0; i < browserList.size(); i++) {  
  4.     Map map = (Map) browserList.get(i);  
  5.     //填充Bar,并给出提示  
  6.     barList.add(new Bar((Integer) map.get("statCount")).setTooltip("#val#次"));  
  7.     //填充y轴  
  8.     xLabel.add(new Label((String) map.get("statVar")));  
  9. }  
  10. //柱状图设置  
  11. BarChart barChart=new BarChart(BarChart.Style.GLASS);  
  12. barChart.addBars(barList);  
  13. barChart.setColour("#6666FF");  
  14. barChart.setText("使用者数量");  
  15. //图表设置  
  16. Chart chart = new Chart("用户浏览器使用量分布");  
  17. chart.setXAxis(labels);  
  18. chart.setYAxis(range);  
  19. chart.addElements(barChart);  

    我们得到如下的柱状图。 
 
   最后一种是饼状图,下面我们来画饼。 
Java代码   收藏代码
  1. //饼状图  
  2. PieChart pieChart = new PieChart();  
  3. for (int i = 0; i < browserList.size(); i++) {  
  4.     Map map = (Map) browserList.get(i);  
  5.     //填充x轴  
  6.     dataSet.add((Integer) map.get("statCount"));  
  7.     //饼状图添加块  
  8.     pieChart.addSlice((Integer) map.get("statCount"), (String) map.get("statVar"));  
  9. }  
  10. //饼状图设置  
  11. pieChart.setColours("#d01f3c", "#356aa0", "#C79810");  
  12. pieChart.setText("使用者数量");  
  13. pieChart.setRadius(180); //饼图的半径  
  14. pieChart.setTooltip("#val# / #total#<br>#percent#");  
  15. //图表设置  
  16. Chart chart = new Chart("用户浏览器使用量分布");  
  17. chart.setXAxis(labels);  
  18. chart.setYAxis(range);  
  19. chart.addElements(pieChart);  

    生成的饼状图如下: 
 
    OFC接收一个JSON格式的文本用来填充Flash,Flash解析这段文本就生成了漂亮的图表。当然OFC的设置还有很多,可以做出非常炫的效果,这里就不深入研究了,当然就是set一些属性罢了。最后我们还是看一下JFreeChart的吧。 
 
    希望对使用者有用,欢迎交流探讨更深入内容。

转载于:https://www.cnblogs.com/huangcongcong/p/4754022.html

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/anzhi8360/article/details/102174768

智能推荐

黑马程序员——集合框架-程序员宅基地

-----------android培训、java培训、java学习型技术博客、期待与您交流! ------------一、介绍集合框架的结构1.1 Collection 与 CollectionsCollection是集合类的上级接口,继承他的主要有List、Set。Collections 是是针对集合类的一个帮助类,他提供一系列静态方法实现对各种集合的搜索、排序、

easyui datagrid 不显示分页栏_datagrid分页栏被挤到屏幕外边-程序员宅基地

easyui datagrid 不显示分页栏 在页面打开 F12 控制台,查看分页栏是否存在 分页栏的class为 l-btn-left l-btn-icon-left ,发现此分页栏存在,只是没有显示在屏幕内,被挤出屏幕datagrid 控件在使用了 pagination: true 属性,并且数据不出错的情况下,分页栏不显示根据 easyui的官方文档查询对应属性发现多了一个 fi..._datagrid分页栏被挤到屏幕外边

idea 彻底删除项目中子模块-程序员宅基地

使用idea打开需要删除的项目,在项目文件上右击选择Remove Module或者按Delete键 之后会弹出删除提示,“Remove Module 'xxx' from the project? No files will be deleted.”,意思是移除指定模块,但没有文件被删除,就是说,模块移除了,磁盘上的文件还在 点击确认之后,可以看到列表中还是存在些文件,这些文件是模块之外的文件,上面删除的只是项目的模块 可以在文件上右击选择Show ...

快速功能点度量方法估算软件规模基本过程是什么? ...-程序员宅基地

 快速功能点度量方法是一种软件规模度量方法,可采用预估功能点和估算功能点进行软件项目规模的估算和测量。  使用快速功能点度量方法估算软件项目规模的过程可分为6步。  第1步:确定应用类型。  A、 新开发:识别所有新增功能。  B、 增强开发:识别变化功能;包括新增、修改及删除。  C、 已有系统计数:识别最终交付功能。  ..._功能点方法是一种用于计算软件规模的方法

js中!和!!的区别及用法-程序员宅基地

js中!的用法是比较灵活的,它除了做逻辑运算常常会用!做类型判断,可以用!与上对象来求得一个布尔值,1、!可将变量转换成boolean类型,null、undefined和空字符串取反都为true,其余都为false。1 !null=true3 !undefined=true5 !''=true6 !0=true7 !100=false9 !'abc'=false...

Android腾讯X5内核WebView加载失败原因_腾讯x5 webview 失败地址 bytedance://dispatch_message-程序员宅基地

网上集成腾讯X5内核方法有很多了,我就不阐述了,简单记录一下加载X5内核失败原因运行官方demo一点毛病也没有,自己创建modul运行也没问题 ,一放到自己的项目就永远初始化失败,最后发现是这个原因:这是官方demo里的配置:ndk { //选择要添加的对应cpu类型的.so库 不能添加arm64-v8a 不然x5内核加载不上去 abiFilters "armeabi", "armeabi-v7a", "x86", "mips"}而我原本项目中为了兼容arm64-v8a 把他_腾讯x5 webview 失败地址 bytedance://dispatch_message

随便推点

mysql必知必会 create_mysql必知必会第一节-程序员宅基地

SQL(Structured Query Language 即结构化查询语言)SQL语言主要用于存取数据、查询数据、更新数据和管理关系数据库系统,SQL语言由IBM开发。SQL语言分为3种类型:DDL语句数据库定义语言: 数据库、表、视图、索引、存储过程,例如CREATE DROP ALTERDML语句数据库操纵语言: 插入数据INSERT、删除数据DELETE、更新数据UPDATE、查询数据SE..._mysql必知必会中source create失败

LeetcodeMedium-【面试题46. 把数字翻译成字符串】_给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”-程序员宅基地

给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”,……,11 翻译成 “l”,……,25 翻译成 “z”。一个数字可能有多个翻译。请编程实现一个函数,用来计算一个数字有多少种不同的翻译方法。示例 1:输入: 12258输出: 5解释: 12258有5种不同的翻译,分别是"bccfi", “bwfi”, “bczi”, “mcfi"和"mzi”..._给定一个数字,我们按照如下规则把它翻译为字符串:0 翻译成 “a” ,1 翻译成 “b”

常用消息队列对比-程序员宅基地

作为中间件,消息队列是分布式应用间交换信息的重要组件。消息队列可驻留在内存或磁盘上, 队列可以存储消息直到它们被应用程序读走。通过消息队列,应用程序可以在不知道彼此位置的情况下独立处理消息,或者在处理消息前不需要等待接收此消息。所以消息队列可以解决应用解耦、异步消息、流量削锋等问题,是实现高性能、高可用、可伸缩和最终一致性架构中不可以或缺的一环。下面对消息队列就直接使用MQ表示。...

关于docker容器中修改/etc/hosts文件_docker /etc/hosts-程序员宅基地

第一部分:root用户对于root用户,这个修改起来还是比较方便呢。 容器启动起来修改成功后,下次容器重启会丢失,因此,我们需要将ip hostname 在做镜像的时候写进去。CMD命令,启动容器的入口。可以在这个shell 脚本中加入:echo "ip hostname" &gt;&gt; /etc/hosts 文件中。对于写入的对应关系比较多的情况下。可以将其写入一个文件中,然..._docker /etc/hosts

HTML- HTML&CSS-程序员宅基地

HTML标签:表单标签* 表单: * 概念:用于采集用户输入的数据的。用于和服务器进行交互。 * form:用于定义表单的。可以定义一个范围,范围代表采集用户数据的范围 * 属性: * action:指定提交数据的URL * method:指定提交方式 * 分类:一共7种,2种比较常用 ...

在玩二维码扫描解码时碰到的问题-程序员宅基地

今天老大出差,没人给任务,闲来无事就玩玩与公司相关的一些小Demo。二维码生成简单,固定不变的代码,玩来玩去还是这些代码代码如下:button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View view)