FusionCharts报表在Android上的实现

分类:android开发 84人阅读 评论(0) 收藏 举报

前言:最近在做一个第三方App,涉及到Android图表显示,图表数据来自后台,需要联网动态获取后台数据,然后加载到报表中显示。Android这边报表方面的实现一直在考虑是否需要谷歌提供的第三方库achartengine来实现,但考虑到和IOS的一致问题。同时,achartengine实现的报表效果并不是那么美观。鉴于FusionCharts在IOS上实现的效果非常不错,决定尝试在android上实现和IOS使用相同的报表组件。


.什么是FusionCharts

简单来说,FusionCharts是一个Flash的图表组件(同时也可以通过javascrit渲染实现),可以用来制作数据动画图表,还有杠杠的跨平台性。

FusionCharts在Web上实现比较多,还有IOS上也经常用到,但是Android这边的实现,FusionCharts官网只字不提。汗...自己摸索了好一段时间。而且有一个问题,Android这边显示这个报表需要安装Adobe。这是因为Android的WebView组件不支持Flash播放,所以显示报表的时候需要安装Adobe player。这是个瓶颈。不过Android也可以用javaScrit渲染实现,但是会有细微的差异。Flash动画播放也会有一定的缺陷。不过,总体来说,还是可以接受。

FusionCharts的官网和源生组件下载地址:http://www.fusioncharts.comhttp://www.fusioncharts.com/download/


二.Android上的实现。

1.前期准备工作:

链接到FusionCharts源生组件下载地址,下载相关的源生组件,包括有各种类型报表对应的js文件和swf(flash文件)。

将需要用到的报表类型组件添加到android工程asset目录下(可在asset目录下再创建个子目录存放js或swf)。

如下图截图,是本博文android工程中用到的报表组件。


asset-js目录存放的是FusionCharts开发必备的一些js文件,asset-swf存放的是FusionCharts各种类型报表对应的flash文件。asset-data存放的是报表需要显示的静态数据,在xml中定义。这些是写死的数据,在实际开发中,需要动态传递报表数据。


2.本博文实现的android demo效果如下截图(报表加载时会有动画效果)

-----3D柱状图--->


-----3D饼图--->

3.MainActivity代码如下:

[java] view plain copy
  1. packagecom.eking.android.fusionchartsjs;
  2. importjava.util.ArrayList;
  3. importjava.util.HashMap;
  4. importjava.util.List;
  5. importjava.util.Map;
  6. importandroid.app.AlertDialog;
  7. importandroid.app.ListActivity;
  8. importandroid.content.DialogInterface;
  9. importandroid.content.Intent;
  10. importandroid.content.DialogInterface.OnClickListener;
  11. importandroid.content.pm.PackageInfo;
  12. importandroid.content.pm.PackageManager;
  13. importandroid.net.Uri;
  14. importandroid.os.Bundle;
  15. importandroid.view.View;
  16. importandroid.widget.ListView;
  17. importandroid.widget.SimpleAdapter;
  18. publicclassMainActivityextendsListActivity{
  19. privateString[]mChartsName;
  20. privateString[]mChartsSign;
  21. privateIntentmIntent;
  22. @Override
  23. protectedvoidonCreate(BundlesavedInstanceState){
  24. super.onCreate(savedInstanceState);
  25. initialize();
  26. setListAdapter(newSimpleAdapter(this,getListValues(),android.R.layout.simple_list_item_1,
  27. newString[]{"name"},newint[]{android.R.id.text1}));
  28. }
  29. privatevoidinitialize(){
  30. mChartsName=newString[]{"折线图","面积图","2D柱状图","3D柱状图","2D饼图","3D饼图","多重数据堆积图","组合图",
  31. "不同单位的多数据集组合图","散点图","气泡图","网格图表","中国地图"};
  32. mChartsSign=newString[]{"Line","Area2D","Column2D","Column3D","Pie2D","Pie3D",
  33. "StackedColumn3D","MSCombi2D","MSColumn3DLineDY","Scatter","Bubble","SSGrid","FCMap_China2"};
  34. mIntent=newIntent(this,ChartsShowActivity.class);
  35. }
  36. privateList<Map<String,String>>getListValues(){
  37. List<Map<String,String>>values=newArrayList<Map<String,String>>();
  38. intlength=mChartsName.length;
  39. for(inti=0;i<length;i++){
  40. Map<String,String>v=newHashMap<String,String>();
  41. v.put("name",mChartsName[i]);
  42. values.add(v);
  43. }
  44. returnvalues;
  45. }
  46. @Override
  47. protectedvoidonListItemClick(ListViewl,Viewv,intposition,longid){
  48. super.onListItemClick(l,v,position,id);
  49. if(checkAdobe()){
  50. mIntent.putExtra("chartsSign",mChartsSign[position]);
  51. startActivity(mIntent);
  52. }else{
  53. installAdobe();
  54. }
  55. }
  56. privatebooleancheckAdobe(){
  57. PackageManagerpm=getPackageManager();
  58. List<PackageInfo>infoList=pm.getInstalledPackages(PackageManager.GET_SERVICES);
  59. for(PackageInfoinfo:infoList){
  60. if("com.adobe.flashplayer".equals(info.packageName)){
  61. returntrue;
  62. }
  63. }
  64. returnfalse;
  65. }
  66. privatevoidinstallAdobe(){
  67. newAlertDialog.Builder(this).setTitle(R.string.dialog_title).setPositiveButton("ok",newOnClickListener(){
  68. @Override
  69. publicvoidonClick(DialogInterfacedialog,intwhich){
  70. Intentintent=newIntent("android.intent.action.VIEW");
  71. intent.setData(Uri.parse("market://details?id=com.adobe.flashplayer"));
  72. startActivity(intent);
  73. finish();
  74. }
  75. }).setNegativeButton("cancel",newOnClickListener(){
  76. @Override
  77. publicvoidonClick(DialogInterfacedialog,intwhich){
  78. }
  79. }).show();
  80. }
  81. }

4.ChartsShowActivity代码如下:

[java] view plain copy
  1. packagecom.eking.android.fusionchartsjs;
  2. importjava.io.StringWriter;
  3. importjava.util.ArrayList;
  4. importjava.util.List;
  5. importorg.codehaus.jackson.JsonGenerator;
  6. importorg.codehaus.jackson.map.ObjectMapper;
  7. importandroid.app.Activity;
  8. importandroid.content.Intent;
  9. importandroid.os.Bundle;
  10. importandroid.util.Log;
  11. importandroid.webkit.WebSettings;
  12. importandroid.webkit.WebView;
  13. importcom.eking.android.fusionchartsjs.bean.ChartsDataEntity;
  14. importcom.eking.android.fusionchartsjs.bean.ChartsEntity;
  15. importcom.eking.android.fusionchartsjs.bean.DataSetEntity;
  16. publicclassChartsShowActivityextendsActivity{
  17. privateWebViewmWebView;
  18. privateStringmFlashType;
  19. privateStringmChartData;
  20. privateStringmJsonString;
  21. privateChartsDataEntitymChartsDataEntity;
  22. privateList<DataSetEntity>mDataSets;
  23. @Override
  24. protectedvoidonCreate(BundlesavedInstanceState){
  25. super.onCreate(savedInstanceState);
  26. setContentView(R.layout.layout_show_charts);
  27. Intentintent=getIntent();
  28. Stringsign=intent.getStringExtra("chartsSign");
  29. initialize();
  30. loadCharts(sign);
  31. }
  32. privatevoidinitialize(){
  33. mWebView=(WebView)findViewById(R.id.webview);
  34. mWebView.getSettings().setJavaScriptEnabled(true);
  35. mWebView.getSettings().setPluginState(WebSettings.PluginState.ON);
  36. mWebView.setHorizontalScrollbarOverlay(true);
  37. mWebView.setVerticalScrollbarOverlay(true);
  38. //设置是否支持缩放(手指伸缩操作)
  39. mWebView.getSettings().setBuiltInZoomControls(true);
  40. //设置是否显示网络图像
  41. mWebView.getSettings().setBlockNetworkImage(true);
  42. //设置是否启用或禁止WebView访问文件数据
  43. mWebView.getSettings().setAllowFileAccess(true);
  44. //设置默认文本编码格式
  45. mWebView.getSettings().setDefaultTextEncodingName("UTF-8");
  46. //mWebView.loadUrl("file:///android_asset/demo.html");
  47. //初始化Json格式的表数据
  48. /*mJson="{\"chart\":{\"caption\":\"MonthlySalesSummary\",\"subcaption\":\"Fortheyear2014\","+
  49. "\"xaxisname\":\"Month\",\"yaxisname\":\"Sales\",\"numberprefix\":\"$\"},"+
  50. "\"data\":[{\"label\":\"January\",\"value\":\"17400\"},{\"label\":\"February\",\"value\":\"19800\"},"+
  51. "{\"label\":\"March\",\"value\":\"21800\"},{\"label\":\"April\",\"value\":\"23800\"},"+
  52. "{\"label\":\"May\",\"value\":\"29600\"},{\"label\":\"June\",\"value\":\"27600\"},"+
  53. "{\"label\":\"July\",\"value\":\"31800\"},{\"label\":\"August\",\"value\":\"39700\"},"+
  54. "{\"label\":\"September\",\"value\":\"37800\"},{\"label\":\"October\",\"value\":\"21900\"},"+
  55. "{\"label\":\"November\",\"value\":\"32900\"},{\"label\":\"December\",\"value\":\"39800\"}]}";
  56. */
  57. //定义Json格式的数据
  58. mJsonString="{\"chart\":{\"caption\":\"2014季度销售报表汇总\",\"subcaption\":\"2014季度\","+
  59. "\"xaxisname\":\"销售月份\",\"yaxisname\":\"销售额度\",\"numberprefix\":\"$\"},"+
  60. "\"data\":[{\"label\":\"一月\",\"value\":\"17400\"},{\"label\":\"二月\",\"value\":\"19800\"},"+
  61. "{\"label\":\"三月\",\"value\":\"21800\"},{\"label\":\"四月\",\"value\":\"23800\"},"+
  62. "{\"label\":\"五月\",\"value\":\"29600\"},{\"label\":\"六月\",\"value\":\"27600\"},"+
  63. "{\"label\":\"七月\",\"value\":\"31800\"},{\"label\":\"八月\",\"value\":\"39700\"},"+
  64. "{\"label\":\"九月\",\"value\":\"37800\"},{\"label\":\"十月\",\"value\":\"21900\"},"+
  65. "{\"label\":\"十一月\",\"value\":\"32900\"},{\"label\":\"十二月\",\"value\":\"39800\"}]}";
  66. }
  67. /*根据图表的Json格式创建对应的对象,
  68. *对对象赋值,然后再将对象转化Json格式数字
  69. */
  70. privateStringgetJsonFromBean(){
  71. mChartsDataEntity=newChartsDataEntity();
  72. mDataSets=newArrayList<DataSetEntity>();
  73. //ChartsEntity对象定义了图表属性
  74. ChartsEntitychart=newChartsEntity();
  75. chart.setCaption("2014季度销售报表汇总");
  76. chart.setSubcaption("2014季度");
  77. chart.setXaxisname("销售月份");
  78. chart.setYaxisname("销售额度");
  79. chart.setNumberprefix("$");
  80. mChartsDataEntity.setChart(chart);
  81. initDataSet("一月","17400");
  82. initDataSet("二月","19800");
  83. initDataSet("三月","21800");
  84. initDataSet("四月","23800");
  85. initDataSet("五月","29600");
  86. initDataSet("六月","27600");
  87. initDataSet("七月","31800");
  88. initDataSet("八月","39700");
  89. initDataSet("九月","37800");
  90. initDataSet("十月","21900");
  91. initDataSet("十一月","32900");
  92. initDataSet("十二月","39800");
  93. initDataSet("一月","17400");
  94. ObjectMapperobjectMapper=newObjectMapper();
  95. try{
  96. StringWritersw=newStringWriter();
  97. JsonGeneratorjsonGenerator=objectMapper.getJsonFactory().createJsonGenerator(sw);
  98. //objectMapper.writeValue(jsonGenerator,mChartsDataEntity);
  99. jsonGenerator.writeObject(mChartsDataEntity);
  100. jsonGenerator.close();
  101. Stringjson=sw.toString();
  102. Log.d("TAG1","json-->"+json);
  103. returnjson;
  104. }catch(Exceptione){
  105. //TODO:handleexception
  106. e.printStackTrace();
  107. }
  108. returnnull;
  109. }
  110. privatevoidinitDataSet(Stringmonth,Stringsale){
  111. //DataSetEntity对象定义了图表的一组数据
  112. DataSetEntitydataSet=newDataSetEntity();
  113. dataSet.setLabel(month);
  114. dataSet.setValue(sale);
  115. mDataSets.add(dataSet);
  116. mChartsDataEntity.setData(mDataSets);
  117. }
  118. //加载显示图表
  119. privatevoidloadCharts(Stringsign){
  120. if(sign.endsWith("Line")){
  121. mFlashType="swf/Line.swf";
  122. mChartData="data/sale_data.xml";
  123. }elseif(sign.equals("Area2D")){
  124. //以Json格式传图表数据
  125. mFlashType="swf/Area2D.swf";
  126. mChartData=getJsonFromBean();
  127. mWebView.loadDataWithBaseURL("file:///android_asset/",getStringForHtmlByJson(mFlashType,mChartData),"text/html",
  128. "utf-8",null);
  129. return;
  130. }elseif(sign.equals("Column2D")){
  131. mFlashType="swf/Column2D.swf";
  132. mChartData="data/Column2DData.xml";
  133. }elseif(sign.equals("Column3D")){
  134. //以Json格式传图表数据
  135. mFlashType="swf/Column3D.swf";
  136. mChartData=mJsonString;
  137. mWebView.loadDataWithBaseURL("file:///android_asset/",getStringForHtmlByJson(mFlashType,mChartData),"text/html",
  138. "utf-8",null);
  139. return;
  140. }elseif(sign.equals("Pie2D")){
  141. mFlashType="swf/Pie2D.swf";
  142. mChartData="data/sale_data.xml";
  143. }elseif(sign.equals("Pie3D")){
  144. mFlashType="swf/Pie3D.swf";
  145. mChartData="data/sale_data.xml";
  146. }elseif(sign.equals("StackedColumn3D")){
  147. mFlashType="swf/StackedColumn3D.swf";
  148. mChartData="data/sale_data_StackedColumn3D.xml";
  149. }elseif(sign.equals("MSCombi2D")){
  150. mFlashType="swf/MSCombi2D.swf";
  151. mChartData="data/sale_data_MSCombi2D.xml";
  152. }elseif(sign.equals("MSColumn3DLineDY")){
  153. mFlashType="swf/MSColumn3DLineDY.swf";
  154. mChartData="data/sale_data_MSColumn3DLineDY.xml";
  155. }elseif(sign.equals("Scatter")){
  156. mFlashType="swf/Scatter.swf";
  157. mChartData="data/ScatterData.xml";
  158. }elseif(sign.equals("Bubble")){
  159. mFlashType="swf/Bubble.swf";
  160. mChartData="data/BubbleData.xml";
  161. }elseif(sign.equals("SSGrid")){
  162. mFlashType="swf/SSGrid.swf";
  163. mChartData="data/sale_data.xml";
  164. }elseif(sign.equals("FCMap_China2")){
  165. mFlashType="swf/FCMap_China2.swf";
  166. mChartData="data/MapData.xml";
  167. }
  168. /*由于FusionCharts.js和flash资源均在资源目录asset下,所以第一个参数需要添加该路径。
  169. *否则资源将无法加载显示
  170. */
  171. mWebView.loadDataWithBaseURL("file:///android_asset/",getStringForHtml(mFlashType,mChartData),"text/html",
  172. "utf-8",null);
  173. }
  174. /**
  175. *报表数据静态定义在XML文件中,载入组件中显示。
  176. *@paramflashType报表组件类型
  177. *@paramchartDataxml文件路径
  178. *@return拼接的html文件代码
  179. */
  180. privateStringgetStringForHtml(StringflashType,StringchartData){
  181. Stringsummary="<html>"+"<head>"+"<title>MyFirstchartusingFusionChartsXT-UsingJavaScript</title>"
  182. +"<scripttype=\"text/javascript\"src=\"js/FusionCharts.js\"></script>"+"</head>"+"<body>"
  183. +"<divid=\"chartContainer\">FusionChartsXTwillloadhere!</div>"
  184. +"<scripttype=\"text/javascript\">"+"varmyChart=newFusionCharts('"+flashType
  185. +"',\"myChartId\",\"300\",\"400\",\"0\",\"1\");"+"myChart.setXMLUrl('"+chartData+"');"
  186. +"myChart.render(\"chartContainer\");"+"</script>"+"</body>"+"</html>";
  187. returnsummary;
  188. }
  189. /**
  190. *传递Json格式数据,作为报表显示数据。实现后台获取动态数据在报表中显示。
  191. *@paramflashType报表组件类型
  192. *@paramchartData报表显示数据
  193. *@return拼接的html文件代码
  194. */
  195. privateStringgetStringForHtmlByJson(StringflashType,StringchartData){
  196. Stringsummary="<html>"+"<head>"+"<title>MyFirstchartusingFusionChartsXT-UsingJavaScript</title>"
  197. +"<scripttype=\"text/javascript\"src=\"js/FusionCharts.js\"></script>"+"</head>"+"<body>"
  198. +"<divid=\"chartContainer\">FusionChartsXTwillloadhere!</div>"
  199. +"<scripttype=\"text/javascript\">"+"varmyChart=newFusionCharts('"+flashType
  200. +"',\"myChartId\",\"300\",\"400\",\"0\",\"1\");"+"myChart.setJSONData('"+chartData+"');"
  201. +"myChart.render(\"chartContainer\");"+"</script>"+"</body>"+"</html>";
  202. returnsummary;
  203. }
  204. }

5.ChartsShowActivity的布局文件layout_show_charts代码如下:

[html] view plain copy
  1. <LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"
  2. xmlns:tools="http://schemas.android.com/tools"
  3. android:layout_width="match_parent"
  4. android:layout_height="match_parent"
  5. >
  6. <WebView
  7. android:id="@+id/webview"
  8. android:layout_width="fill_parent"
  9. android:layout_height="fill_parent"
  10. />
  11. </LinearLayout>

到此,FusionCharts在android上的实现介绍就结束了,demo下载地址链接如下:
http://download.csdn.net/detail/stevenhu_223/7649001

更多相关文章

  1. Android(安卓)采用HttpClient提交数据到服务器
  2. 初学Android,数据存储之使用SQLite数据库(四十六)
  3. Android(安卓)adapter 数据适配器
  4. MVC架构设计与三层模型 & MVP思想精髓与解耦
  5. Android利用Fiddler进行网络数据抓包
  6. Android--创建和使用数据库详细指南
  7. Android实现图表绘制和展示
  8. ANDROID音频系统散记之二:resample-1
  9. mybatisplus的坑 insert标签insert into select无参数问题的解决

随机推荐

  1. Android和iOS人才招聘出现拐点 低能人才
  2. Android(安卓)64bit系统中app以32bit运行
  3. Android研究院之应用开发线程池的经典使
  4. 软件工程之四则运算开发感悟与收获
  5. android代码混淆时,如何防止第三方jar包被
  6. android wear那些事--通过蓝牙调试
  7. [置顶] Android进程管理(详解)
  8. 我的Android进阶之旅------>Android使用9
  9. android中YUV转RGB的方法
  10. 如何去准备Android技术面试(简历,技术面)