寫在開始之前
之前在項目中使用過MPAndroidChart 顯示過資料圖表,現在需要使用HTML + Echart 來顯示,寫了一個Demo,DEMO中實作了線圖,餅圖,還有柱狀圖。
示例代碼位址:點選跳轉到github
使用到的開源項目
- EChart 庫 -js
- 版本:2.2.7
- EChart java 對象庫 這是一個針對ECharts3.x(2.x)版本的Java類庫,實作了所有ECharts中的Json結構對應的Java對象,并且可以很友善的建立Option。這個庫引用了Gson,是以build.gradle 中也要加入GSON 的依賴。
- 版本 2.2.7
JS 和 html 編寫
為友善測試,html頁面和js代碼放置于項目的assets 目錄中,Android代碼通路路徑為:file:///android_asset/jsWeb/echart.html
html 頁面編寫
- 在head中引入 js 腳本,主要代碼如下:(點選檢視全部代碼:echart.html)
<head> <!-- 導入script --> <script src="http://echarts.baidu.com/echarts2/doc/example/www/js/echarts.js"></script> <script src="./android.js"></script> </head>
- body中請求需要的EChart腳本,并添加對應控件,主要代碼如下: ( 點選檢視全部代碼:echart.html) 。 我在其中添加了一個js中指定資料的EChart 表格用于測試
<div id="main" style="height:400px"></div> <script type="text/javascript"> // 路徑配置 require.config({ paths: { echarts: 'http://echarts.baidu.com/echarts2/doc/example/www/js' //echarts: './www/js' } }); // 使用 require( [ 'echarts', 'echarts/chart/line', // 使用柱狀圖就加載line子產品,按需加載 'echarts/chart/bar', // 使用柱狀圖就加載bar子產品,按需加載 'echarts/chart/pie', // 使用柱狀圖就加載pie子產品,按需加載 ], function (ec) { // 基于準備好的dom,初始化echarts圖表 var myChart = ec.init(document.getElementById('main')); //設定資料 var option = { // .... 資料部分 }; // 為echarts對象加載資料 myChart.setOption(option); } ) </script> <hr/> <p> <b>從Android 代碼中擷取資料繪制圖表</b><br/> <button onClick="loadALineChart()" style="height:40px">線狀圖</button> <button onClick="loadAChart(2)" style="height:40px">餅狀圖</button> <button onClick="loadAChart(1)" style="height:40px">柱狀圖</button> <p id="textcontent">沒有内容</p> <div id="chart2" style="height:400px"/> </p>
JS 腳本
這裡有一點要注意:Android WebView 提供的接口傳回String 類型的json option 字元串,而JS 端接受到字元串後需要用JSON.parse 方法轉化成js的Object 對象,隻有轉換成對象之後才可以傳入到Echart的setOption 方法中顯示出來。
主要代碼如下,點選檢視全部代碼
function toast(msg){
Android.showToast(msg);
}
function loadALineChart(){
// 必須加JOSN.parse 轉換資料類型
var option = JSON.parse(Android.getLineChartOptions());
var chart2Doc = document.getElementById('chart2');
var myChart2 = require('echarts').init(chart2Doc);
myChart2.setOption(option);
document.getElementById('textcontent').innerHTML=option;
toast(option);
}
/**
type : 1 - 餅狀圖
2 - 柱狀圖
*/
function loadAChart(type){
// 必須用JSON.parse() 轉換一下,才可以顯示,否則資料類型會不對
var option = JSON.parse(Android.getPieChartOptions(type));
var chart2Doc = document.getElementById('chart2');
var myChart2 = require('echarts').init(chart2Doc);
myChart2.setOption(option);
document.getElementById('textcontent').innerHTML=option;
}
Android 代碼編寫
1. WebAppInterface 定義和實作
點選檢視全部檔案内容
/**
* 注入到JS裡的對象接口
*/
class WebAppInterface {
Context mContext;
public WebAppInterface(Context c) {
mContext = c;
}
/**
* 擷取
*
* @return
*/
@JavascriptInterface
public String getLineChartOptions() {
GsonOption option = markLineChartOptions();
LogUtils.d(option.toString());
return option.toString();
}
@JavascriptInterface
public void showToast(String msg) {
Toast.makeText(mContext, msg, Toast.LENGTH_SHORT).show();
}
/**
* PieChart 或者柱狀圖資料示例
* @param type 1 - 餅狀圖資料; 2 - 柱狀圖資料
* @return
*/
@JavascriptInterface
public String getPieChartOptions(int type) {
mWebView.post(new Runnable() {
@Override
public void run() {
showDialog();
}
});
try {
Thread.currentThread().sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//位址:http://echarts.baidu.com/doc/example/pie7.html
GsonOption option = new GsonOption();
// 設定标題
option.title(new Title().text("某站點使用者通路來源").subtext("純屬虛構").x(X.center));
if(type == 2) {
option.tooltip().trigger(Trigger.item).formatter("{a} <br/>{b} : {c} ({d}%)");
}else if(type == 1){
option.tooltip().trigger(Trigger.item).formatter("{a} <br/>{b} : {c}");
}
// 設定圖例
option.legend().data("直接通路", "郵件營銷", "聯盟廣告", "視訊廣告", "搜尋引擎").orient(Orient.vertical).x(X.left);
// 是否可以拖動以計算
option.calculable(true);
if(type == 2){
// 構造資料
Pie pie1 = new Pie("通路來源");
pie1.type(SeriesType.pie).radius("45%").center("50%","60%");
pie1.data(new Data("直接通路",335),
new Data("郵件營銷",310),
new Data("聯盟廣告",234),
new Data("視訊廣告",135),
new Data("搜尋引擎",1548)
);
option.series(pie1);
}else if(type ==1) {
// 建構柱狀資料
option.xAxis(new CategoryAxis().name("通路來源").data("視訊廣告","搜尋引擎","聯盟廣告","郵件營銷","直接通路"));
option.yAxis(new ValueAxis());
Bar bar = new Bar("通路來源");
bar.data(11,4,14,45,67,88);
option.series(bar);
}
Log.d("TAG",option.toString());
mWebView.post(new Runnable() {
@Override
public void run() {
dismissDialog();
}
});
return option.toString();
}
@JavascriptInterface
public GsonOption markLineChartOptions() {
GsonOption option = new GsonOption();
option.legend("高度(km)與氣溫(°C)變化關系");
option.toolbox().show(true).feature(Tool.mark, Tool.dataView, new MagicType(Magic.line, Magic.bar), Tool.restore, Tool.saveAsImage);
option.calculable(true);
option.tooltip().trigger(Trigger.axis).formatter("Temperature : <br/>{b}km : {c}°C");
ValueAxis valueAxis = new ValueAxis();
valueAxis.axisLabel().formatter("{value} °C");
option.xAxis(valueAxis);
CategoryAxis categoryAxis = new CategoryAxis();
categoryAxis.axisLine().onZero(false);
categoryAxis.axisLabel().formatter("{value} km");
categoryAxis.boundaryGap(false);
categoryAxis.data(0, 10, 20, 30, 40, 50, 60, 70, 80);
option.yAxis(categoryAxis);
Line line = new Line();
line.smooth(true).name("高度(km)與氣溫(°C)變化關系").data(15, -50, -56.5, -46.5, -22.1, -2.5, -27.7, -55.7, -76.5).itemStyle().normal().lineStyle().shadowColor("rgba(0,0,0,0.4)");
option.series(line);
return option;
}
}
2. WebView 上啟用JavaScript 并注入Java對象:
點選檢視全部檔案内容
webSettings.setJavaScriptEnabled(true);
mWebView.addJavascriptInterface(new WebAppInterface(this), "Android");
作者:HanlyJiang
連結:http://www.jianshu.com/p/7b226e0e5f12
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。