更多例項見: echarts.baidu.com/examples.ht…
前言
使用百度前度Echart框架: echarts.baidu.com/ gitee.com/free/EChart… 參考iOS封裝實現: github.com/Pluto-Y/iOS… 等資料對Android版本的實現進行簡單的封裝 時間不是很充裕,只能在零碎時間上來一點一點補充,因此肯定會出現許多不足之處 希望在未來的某一天自己能封裝的很完善
專案GitHub地址 TAndroidEChart
新增依賴:
- 方式一
Step 1:新增maven { url '[https://jitpack.io](https://jitpack.io/)' } 到project的build.gradle
allprojects {
repositories {
...
maven { url '[https://jitpack.io](https://jitpack.io/)' }
}
}
versionNum為最新版本的值 如:v1.2.1
Step 2: 新增compile 'com.github.tikeyc:TAndroidEChart:versionNum'到你app的build.gradle
dependencies {
compile 'com.github.tikeyc:TAndroidEChart:versionNum'
}
複製程式碼
- 方式二 直接下載完整專案,import一個module:tandroidechartlibrary
如何使用:
xml:
<com.tikeyc.tandroidechartlibrary.TEChartWebView
android:id="@+id/barChartWebView"
android:layout_width="match_parent"
android:layout_height="match_parent">
</com.tikeyc.tandroidechartlibrary.TEChartWebView>
複製程式碼
具體程式碼:
可能後續操作需要重新整理圖表,可以這樣呼叫
(注意:不能在第一時間就用此方法來顯示圖表,因為第一時間html的標籤還未載入完成,不能獲取到標籤值)
barChartWebView. refreshEchartsWithOption(getLineAndBarChartOption());
複製程式碼
public class TBarChartActivity extends TBaseActivity {
@ViewInject(R.id.barChartWebView)
private TEChartWebView barChartWebView;
@Event(R.id.navigationBar_title_tv)
private void titleClick(View view) {
if (!view.isSelected()) {
barChartWebView.refreshEchartsWithOption(getLineChartOptions());
} else {
barChartWebView.refreshEchartsWithOption(getLineAndBarChartOption());
}
view.setSelected(!view.isSelected());
}
@Override
protected void onCreate(Bundle savedInstanceState) {
this.isLandScape = true;
super.onCreate(savedInstanceState);
//設定橫屏
if(this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
setContentView(R.layout.activity_tbar_chart);
initData();
initView();
}
private void initData() {
}
private void initView() {
x.view().inject(this);
//
//navigationBar_title_tv.setText("BarChart");
//開啟除錯模式預設false
barChartWebView.setDebug(true);
//設定資料來源
barChartWebView.setDataSource(new TEChartWebView.DataSource() {
@Override
public GsonOption markChartOptions() {
return getLineAndBarChartOption();
}
});
//新增事件監聽
TEChartConstant.PYEchartAction[] echartActions = {TEChartConstant.PYEchartAction.PYEchartActionLegendSelected, TEChartConstant.PYEchartAction.PYEchartActionClick};
barChartWebView.addEchartActionHandler(echartActions, new TEChartWebView.OnAddEchartActionHandlerResponseResultListener() {
@Override
public void actionHandlerResponseResult(String result) {
//檢視事件資訊 處理事件
/*TEChartConstant.PYEchartAction.PYEchartActionLegendSelected
*
*{"selected":{"蒸發量":true,"降水量":true,"平均溫度":true},"target":"蒸發量","type":"legendSelected","event":{"zrenderX":220.33299255371094,"zrenderY":8.666999816894531,"zrenderFixed":1},"__echartsId":1512031135165}
*/
/*TEChartConstant.PYEchartAction.PYEchartActionClick
*
*{"seriesIndex":1,"seriesName":"降水量","dataIndex":4,"data":28.7,"name":"5月","value":28.7,"type":"click","event":{"zrenderX":261,"zrenderY":209,"zrenderFixed":1}}
*/
}
});
}
/**根據https://mvnrepository.com/artifact/com.github.abel533/ECharts
* 結合http://echarts.baidu.com/examples.html官方例項
* 配置json資料
* @return
*/
public GsonOption getLineAndBarChartOption() {
//http://echarts.baidu.com/echarts2/doc/example/mix1.html
GsonOption option = new GsonOption();
//title
String text = "text";
String subText = "subText";
option.title(text,subText);
//tooltip
Tooltip tooltip = new Tooltip();
tooltip.trigger(Trigger.axis);
option.tooltip(tooltip);
//toolbox
Toolbox toolbox = new Toolbox();
toolbox.show(true);
Map<String, Feature> feature = new HashMap<String, Feature>();
feature.put("mark",new Feature().show(true));
feature.put("dataView",new DataView().show(true).readOnly(false));
feature.put("magicType",new MagicType(Magic.line, Magic.bar).show(true));
feature.put("restore",new Restore().show(true));
feature.put("saveAsImage",new SaveAsImage().show(false));
toolbox.setFeature(feature);
option.toolbox(toolbox);
//calculable
option.setCalculable(true);
//legend
String legend1 = "蒸發量";
String legend2 = "降水量";
String legend3 = "平均溫度";
Legend legend = new Legend();
legend.data(legend1,legend2,legend3);
option.legend(legend);
//grid
// Grid grid = new Grid();
// grid.y2(80);
// option.grid(grid);
//xAxis
List<Axis> xAxis = new ArrayList<Axis>();
CategoryAxis categoryAxis = new CategoryAxis();
{
List xAxisValues = new ArrayList();
for (int i = 1; i <= 12; i++) {
xAxisValues.add(i + "月");
}
categoryAxis.setData(xAxisValues);
}
xAxis.add(categoryAxis);
option.xAxis(xAxis);
//yAxis
List<Axis> yAxis = new ArrayList<Axis>();
{
ValueAxis valueAxis = new ValueAxis();
valueAxis.name("水量");
valueAxis.axisLabel(new AxisLabel().formatter("{value} ml"));
yAxis.add(valueAxis);
}
{
ValueAxis valueAxis = new ValueAxis();
valueAxis.name("溫度");
valueAxis.axisLabel(new AxisLabel().formatter("{value} °C"));
yAxis.add(valueAxis);
}
option.yAxis(yAxis);
//series
List<Series> series = new ArrayList<Series>();
{
Bar bar = new Bar();
bar.name(legend1).type(SeriesType.bar).yAxisIndex(0);
List data = new ArrayList();
double arrays[] = {2.0, 4.9, 7.0, 23.2, 25.6, 76.7, 135.6, 162.2, 32.6, 20.0, 6.4, 3.3};
for (double value : arrays){
data.add(value);
}
bar.setData(data);
series.add(bar);
}
{
Bar bar = new Bar();
bar.name(legend2).type(SeriesType.bar).yAxisIndex(0);
List data = new ArrayList();
double arrays[] = {2.6, 5.9, 9.0, 26.4, 28.7, 70.7, 175.6, 182.2, 48.7, 18.8, 6.0, 2.3};
for (double value : arrays){
data.add(value);
}
bar.setData(data);
series.add(bar);
}
{
Line line = new Line();
line.name(legend3).type(SeriesType.line).yAxisIndex(1);
List data = new ArrayList();
double arrays[] = {2.0, 2.2, 3.3, 4.5, 6.3, 10.2, 20.3, 23.4, 23.0, 16.5, 12.0, 6.2};
for (double value : arrays){
data.add(value);
}
line.setData(data);
series.add(line);
}
option.series(series);
//
return option;
}
public GsonOption getLineChartOptions() {
//地址:http://echarts.baidu.com/echarts2/doc/example/line5.html
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;
}
}
複製程式碼
封裝原始碼:
TEChartWebView控制元件原始碼
public class TEChartWebView extends WebView {
/** 預設false
* 在EChart.html和EChart.js中因開發除錯多處呼叫了function toast(msg) 可以設定為true開啟除錯模式
*/
private boolean isDebug = false;
/**
* 存放在第一時間需要Android呼叫js的function
* 因為在第一次見EChart.html及EChart.js還沒有載入完成,而Java程式碼卻是在第一時間呼叫了
* 所以需要等到html的標籤及js載入成功後再呼叫,在WebViewClient中的onPageFinished方法中
*/
private List<String> shouldCallJsFunctionArray = new ArrayList<String>();
public void setDebug(boolean isDebug) {
this.isDebug = isDebug;
}
public boolean isDebug() {
return isDebug;
}
public TEChartWebView(Context context) {
this(context,null);
}
public TEChartWebView(Context context, AttributeSet attrs) {
this(context, attrs,0);
}
public TEChartWebView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initWebViewClient();
init();
}
private void init() {
//
WebSettings webSettings = getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setSupportZoom(false);
webSettings.setDisplayZoomControls(false);
addJavascriptInterface(new TEChartWebView.WebAppEChartInterface(getContext()), "Android");
loadUrl("file:///android_asset/echartWeb/EChart/EChart.html");
}
private void initWebViewClient () {
setWebViewClient(new WebViewClient(){
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
for (String callJs : shouldCallJsFunctionArray) {
loadUrl(callJs);
}
}
@Override
public void onLoadResource(WebView view, String url) {
super.onLoadResource(view, url);
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
}
});
}
/**重新整理圖表
* java呼叫js的refreshEChartWithGsonOption方法重新整理echart
* 不能在第一時間就用此方法來顯示圖表,因為第一時間html的標籤還未載入完成,不能獲取到標籤值
* 需先設定資料來源DataSource,後續視具體情況來手動重新整理
* @param option
*/
public void refreshEchartsWithOption(GsonOption option) {
if (dataSource == null) {
assert false : "ataSource == null";
}
String optionString = option.toString();
String call = "javascript:refreshEchartsWithOption('" + optionString + "')";
loadUrl(call);
}
/**新增圖表事件響應監聽
* @param echartActions 事件名稱陣列
* @param onAddEchartActionHandlerResponseResultListener 事件點選後的echart返回的事件資訊(echart返回的事件資訊:http://echarts.baidu.com/api.html#events) 響應監聽給開發者
*/
public void addEchartActionHandler(TEChartConstant.PYEchartAction[] echartActions, OnAddEchartActionHandlerResponseResultListener onAddEchartActionHandlerResponseResultListener) {
this.onAddEchartActionHandlerResponseResultListener = onAddEchartActionHandlerResponseResultListener;
//
for (TEChartConstant.PYEchartAction echartAction : echartActions) {
String callString = echartAction.actionValue;
String call = "javascript:addEchartActionHandler('" + callString + "')";
//loadUrl(call);
shouldCallJsFunctionArray.add(call);
}
}
/**移除圖表事件響應監聽
* @param echartAction 事件名稱
*/
public void removeEchartActionHandler(TEChartConstant.PYEchartAction echartAction) {
String callString = echartAction.actionValue;
String call = "javascript:removeEchartActionHandler('" + callString + "')";
loadUrl(call);
}
/**
*顯示Echart自帶的預設樣式的Loading
*/
public void myChartShowLoading() {
String call = "javascript:myChartShowLoading()";
//loadUrl(call);
shouldCallJsFunctionArray.add(call);
}
/**
*隱藏Echart自帶的預設樣式的Loading
*/
public void myChartHideLoading() {
String call = "javascript:myChartHideLoading()";
loadUrl(call);
}
///////////////////////WebAppEChartInterface////////////////////////////////
/**
* js 與 Android原生互動介面
*/
class WebAppEChartInterface {
Context context;
public WebAppEChartInterface(Context context) {
this.context = context;
}
@JavascriptInterface
public void showDebugMessage(String message) {
if (isDebug) LogUtils.e(message);
}
/**
* 獲取圖表配置JSON資料
*
* @return
*/
@JavascriptInterface
public String getChartOptions() {
if (dataSource != null) {
GsonOption option = dataSource.markChartOptions();
LogUtils.d(option.toString());
return option.toString();
}
return null;
}
/**新增圖表事件響應監聽
* @param params echart返回的事件資訊 http://echarts.baidu.com/api.html#events
*/
@JavascriptInterface
public void addEchartActionHandlerResponseResult(String params) {
LogUtils.e(params);
if (onAddEchartActionHandlerResponseResultListener != null) {
onAddEchartActionHandlerResponseResultListener.actionHandlerResponseResult(params);
}
}
/**移除圖表事件響應監聽
* @param params echart返回的事件資訊 http://echarts.baidu.com/api.html#events
*/
@JavascriptInterface
public void removeEchartActionHandlerResponseResult(String params) {
LogUtils.e(params);
}
}
///////////////////////WebAppEChartInterface////////////////////////////////
////////////////////////////資料來源 獲取圖表的JSON配置//////////////////////////////
private DataSource dataSource;
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
//
reload();
}
public DataSource getDataSource() {
return dataSource;
}
public interface DataSource {
GsonOption markChartOptions();
}
////////////////////////////資料來源 獲取圖表的JSON配置//////////////////////////////
////////////////////////////新增事件監聽echart返回的 事件相關屬性(是一個json),將該json返回給開發者使用
///////////////////////////echart返回的事件資訊:http://echarts.baidu.com/api.html#events
private OnAddEchartActionHandlerResponseResultListener onAddEchartActionHandlerResponseResultListener;
public void setOnAddEchartActionHandlerResponseResultListener(OnAddEchartActionHandlerResponseResultListener onAddEchartActionHandlerResponseResultListener) {
this.onAddEchartActionHandlerResponseResultListener = onAddEchartActionHandlerResponseResultListener;
}
public OnAddEchartActionHandlerResponseResultListener getOnAddEchartActionHandlerResponseResultListener() {
return onAddEchartActionHandlerResponseResultListener;
}
public interface OnAddEchartActionHandlerResponseResultListener {
void actionHandlerResponseResult(String result);
}
}
複製程式碼
時間不是很充裕,只能在零碎時間上來一點一點補充,因此肯定會出現許多不足之處 希望在未來的某一天自己能封裝的很完善
專案GitHub地址 https://github.com/tikeyc/TAndroidEChart