FusionCharts报表在Android上的实现

来源:互联网 发布:优化营商环境建议 个人 编辑:程序博客网 时间:2024/06/07 09:56
 

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 plaincopy
  1. package com.eking.android.fusionchartsjs;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.HashMap;  
  5. import java.util.List;  
  6. import java.util.Map;  
  7. import android.app.AlertDialog;  
  8. import android.app.ListActivity;  
  9. import android.content.DialogInterface;  
  10. import android.content.Intent;  
  11. import android.content.DialogInterface.OnClickListener;  
  12. import android.content.pm.PackageInfo;  
  13. import android.content.pm.PackageManager;  
  14. import android.net.Uri;  
  15. import android.os.Bundle;  
  16. import android.view.View;  
  17. import android.widget.ListView;  
  18. import android.widget.SimpleAdapter;  
  19.   
  20. public class MainActivity extends ListActivity {  
  21.   
  22.     private String[] mChartsName;  
  23.     private String[] mChartsSign;  
  24.     private Intent mIntent;  
  25.   
  26.     @Override  
  27.     protected void onCreate(Bundle savedInstanceState) {  
  28.         super.onCreate(savedInstanceState);  
  29.         initialize();  
  30.         setListAdapter(new SimpleAdapter(this, getListValues(), android.R.layout.simple_list_item_1,  
  31.                 new String[] { "name" }, new int[] { android.R.id.text1 }));  
  32.     }  
  33.   
  34.     private void initialize() {  
  35.         mChartsName = new String[] { "折线图" , "面积图" , "2D柱状图" , "3D柱状图" , "2D饼图" , "3D饼图" , "多重数据堆积图" , "组合图" ,  
  36.                 "不同单位的多数据集组合图""散点图""气泡图""网格图表""中国地图"};  
  37.         mChartsSign = new String[] { "Line" , "Area2D" , "Column2D" , "Column3D" , "Pie2D" , "Pie3D" ,  
  38.                 "StackedColumn3D" , "MSCombi2D" , "MSColumn3DLineDY""Scatter""Bubble""SSGrid""FCMap_China2"};  
  39.         mIntent = new Intent(this, ChartsShowActivity.class);  
  40.     }  
  41.   
  42.     private List<Map<String , String>> getListValues() {  
  43.         List<Map<String , String>> values = new ArrayList<Map<String , String>>();  
  44.         int length = mChartsName.length;  
  45.         for (int i = 0; i < length; i++) {  
  46.             Map<String , String> v = new HashMap<String , String>();  
  47.             v.put("name", mChartsName[i]);  
  48.             values.add(v);  
  49.         }  
  50.         return values;  
  51.     }  
  52.   
  53.     @Override  
  54.     protected void onListItemClick(ListView l,View v,int position,long id) {  
  55.         super.onListItemClick(l, v, position, id);  
  56.         if (checkAdobe()) {  
  57.             mIntent.putExtra("chartsSign", mChartsSign[position]);  
  58.             startActivity(mIntent);  
  59.         } else {  
  60.             installAdobe();  
  61.         }  
  62.     }  
  63.       
  64.       
  65.     private boolean checkAdobe() {  
  66.          PackageManager pm = getPackageManager();    
  67.          List<PackageInfo> infoList = pm.getInstalledPackages(PackageManager.GET_SERVICES);  
  68.          for (PackageInfo info : infoList) {    
  69.              if ("com.adobe.flashplayer".equals(info.packageName)) {  
  70.                  return true;  
  71.              }  
  72.          }  
  73.          return false;  
  74.     }  
  75.       
  76.     private void installAdobe() {  
  77.           
  78.         new AlertDialog.Builder(this).setTitle(R.string.dialog_title).setPositiveButton("ok"new OnClickListener() {  
  79.   
  80.             @Override  
  81.             public void onClick(DialogInterface dialog,int which) {  
  82.               
  83.                 Intent intent = new Intent("android.intent.action.VIEW");  
  84.                 intent.setData(Uri.parse("market://details?id=com.adobe.flashplayer"));  
  85.                 startActivity(intent);  
  86.                 finish();  
  87.   
  88.             }  
  89.         }).setNegativeButton("cancel"new OnClickListener() {  
  90.   
  91.             @Override  
  92.             public void onClick(DialogInterface dialog,int which) {  
  93.                   
  94.             }  
  95.         }).show();  
  96.           
  97.     }  
  98. }  

 4.ChartsShowActivity代码如下:

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

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

[html] view plaincopy
  1. <LinearLayout xmlns: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.   
  7.     <WebView  
  8.         android:id="@+id/webview"  
  9.         android:layout_width="fill_parent"  
  10.         android:layout_height="fill_parent"  
  11.          />  
  12.   
  13. </LinearLayout>  

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