在项目中经常会有一些图形报表的功能,对于android的图形报表的实现,可以利用一些开源的android图形报表框架如:achartengine,hellocharts, MPAndroidChar等,这些框架虽然实现的很好,但在实际项目我们需要的图形报表是有设计师设计的,可能我们需要效果这些框架没有提供,或是提供的样式不符合我们的需求,这时候需要我们去修改这些框架,更改它的样式,这就要求我们需要熟悉这些框架的源码,能够举一反三的去修改它,然而说起来简单, 真正改起来并不容易,当然我们也可以自定义view通过绘图来实现,这种方式是最灵活的,但同样自己会绘制一个图形控件也不是能够简单的能够搞定,那么我们改如何能够快速的实现项目中的这些图形报表呢,其实,在web网站的开发中也会经常有各种图形报表的功能,针对这些已经有很多简单易用,功能丰富多样的图形报表框架,那么我们为何不通过webview来调用这些js图形报表框架呢,
下面介绍下如何通过webview来加载一个个人认为比较好些的图形报表框架highcharts(不熟悉的人百度搜索highcharts):
首先介绍下我要实现的效果:如下图,要实现一个区域统计图效果的报表。
首先登陆highcharts (http://www.hcharts.cn/demo/)在线演示平台,通过这平台可以看到highcharts提供了很多效果的图形报表,找到我们需要效果:曲线区域图
如上图 提供的效果与我们需要的效果已经很类似,但还是有些差别,别急, 现在去修改它,修改的同时学会它的使用。如图,点击编辑代码。
如图,左侧是控制报表效果的js代码,我们主要是修改这些代码,这些js代码的方法属性我们也许不熟悉,但没关系,我们可以便尝试修改预览可以明白这些属性是干什么用的。对于类似的图形报表我们经常关注的有 x轴,y轴坐标标注,数据集等实现,阅读左侧的js代码我们发现,只有series节点是设置数值数值,我们不妨猜测我们可以通过修改series节点里,data的值达到修改区域图的y轴对应的值,如图我注释调一个数据对象,点击“运行” 发现 果然只有一条曲线区域图了,修改同时也发现通过修改data对应的值确实是修改区域图的关键点的值了,其它的属性也可以通过尝试学会使用,当然这中方法使用不了解highcharts的人员简单来学习集成highcharts图形报表,如果真正学会highcharts还是需要去通过官方API文件去了解每个属性的用法。
好了,我们已经大概了解highcharts的样子,在实际的项目中,data部分数据肯定是动态,横坐标的星期也有可能是动态的,那么我们改如何来着做呢
html代码:将左侧的data的数据等于成变量,这些变量通过webview接口从android代码传递到js中,
-
<!doctype html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <script type="text/javascript" src="http://cdn.hcharts.cn/jquery/jquery-1.8.3.min.js"></script> <script type="text/javascript" src="http://cdn.hcharts.cn/highcharts/highcharts.js"></script> <script type="text/javascript" src="http://cdn.hcharts.cn/highcharts/exporting.js"></script> <script type="text/javascript"> var result = window.Android.getResult();//调用android中的方法,取得从android传递过来的数据 //alert("result="+result); var jsonData = eval("(" + result + ")"); //将json字符串数据转换为jsonObject对象 //alert("jsonData="+jsonData); var xText = jsonData.xtext;//解析xtext节点数据 //alert("xText="+xText); var data = jsonData.data; //alert("data="+data); var xdata = jsonData.xdata; //alert("xdata="+xdata); $(function () { $('#container').highcharts({ chart: { type: 'areaspline' }, title: { text: '收费统计' }, legend: { layout: 'vertical', align: 'left', verticalAlign: 'top', x: 150, y: 100, floating: true, borderWidth: 1, backgroundColor: '#FFFFFF' }, xAxis: { title: { text: xText }, categories:xdata, plotBands: [{ // visualize the weekend from: 4.5, to: 6.5, //color: 'rgba(68, 170, 213, .2)' color: 'rgba(68, 255, 0, 0)' }] }, yAxis: { title: { text: '收费' } }, tooltip: { shared: true, valueSuffix: ' units' }, credits: { enabled: false }, plotOptions: { areaspline: { fillOpacity: 0.5 } }, series: [{ name: '收费', data: data }] }); }); </script> <style> body{margin:0;padding:0;} </style> </head> <body> <div id="container" style="100%;height:400px"></div> </body> </html>
将上面的代码保存到一个html文件中,拷贝放到工程assets目录下:
下面代码介绍如何通过 webview将参数传递给js
java代码
-
private void initWebView() { activity = this; webview.setVisibility(View.VISIBLE); WebSettings webSettings = webview.getSettings(); url = "file:/android_asset/index3.html"; // 支持JS webSettings.setJavaScriptEnabled(true); webSettings.setDisplayZoomControls(false); // 隐藏webview缩放按钮 webview.addJavascriptInterface(new JsInteration(), "Android"); webview.setWebChromeClient(new WebChromeClient() { }); // 设置进度条 webview.setWebChromeClient(new WebChromeClient() { public void onProgressChanged(WebView view, int progress) { activity.setTitle("小弟正在努力加载中..."); activity.setProgress(progress * 100); if (progress == 100) activity.setTitle(R.string.app_name); } }); webview.setWebViewClient(new WebViewClient() { public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { // Handle the error } @Override public boolean shouldOverrideUrlLoading(WebView view, String url2) { if (Uri.parse(url2).getHost().equals(url)) { // Load the site into the default browser Intent intent = new Intent(Intent.ACTION_VIEW, Uri .parse(url)); startActivity(intent); return true; } // 1:返回false: Load url into the webview // 2:返回true:已浏览器方式 return false; } }); webview.loadUrl(url); } private String showtype; public class JsInteration { @JavascriptInterface public String getResult() { JSONObject jsonObject = new JSONObject(); try { JSONArray jsonArray1 = new JSONArray(); JSONArray jsonArray2 = new JSONArray(); for (int j = 0; j < list2.size(); j++) { //这里的list2是通过接口从服务器取得的数据集合 StatisticsChartInfo statisticsChartInfo = list2.get(j); jsonArray1.put(statisticsChartInfo.getCurrtime()); jsonArray2.put(Double.valueOf(statisticsChartInfo .getRevenue())); } jsonObject.put("xtext", xtext); jsonObject.put("xdata", jsonArray1); jsonObject.put("data", jsonArray2); } catch (JSONException e) { e.printStackTrace(); } LogUtil.d("传递的数据=" + jsonObject.toString()); return jsonObject.toString(); } } @Override protected void onDestroy() { // TODO Auto-generated method stub super.onDestroy(); if (webview!= null) { webview.destroy(); } }
好了,到此为止,我们了解如何通过webview简单的加载js报表框架,在这里抛砖引玉希望有更多高手指出其中的不足之处,能够一起讨论学习,共同进步。