基于HTML5的ichartjs图表组件在Android应用中的使用

一、什么是ichartjs?

ichartjs 是一款基于HTML5的图形库。使用纯javascript语言, 利用HTML5的canvas标签绘制各式图形。 ichartjs致力于为您的应用提供简单、直观、可交互的体验级图表组件。是WEB/APP图表展示方面的解决方案 。如果你正在开发HTML5的应用,ichartjs正好适合您。 ichartjs目前支持饼图、环形图、折线图、面积图、柱形图、条形图。ichartjs是基于Apache License 2.0协议的开源项目。

二、如何使用ichartjs?
在你的html页面中,添加如下javascript引用即可:
<script type="text/javascript" src="ichart.1.2.min.js"></script>

三、ichartjs在Android中的应用
了解过WebApp开发的童鞋应该都知道,Android平台应用开发的另外一种方式,使用WebView加载HTML页面,在HTML页面中实现我们的功能和界面开发,那么Android代码和HTML代码交互就通过JavaScript来实现。ichartjs的使用也是这一套路线。
下面以一个ichartjs的3D柱状图的demo来讲解它在Android中的应用。
首先定义好需要的实体:
package com.example.achartdemo.beans;

public class Contact {
	private String name; // 浏览器的名称
	private double value; // 浏览器对应的所占市场份额值
	private String color; // 在柱形图中所显示的颜色
	
	/**
	 * 构造函数
	 * @param name 浏览器的名称
	 * @param value 浏览器对应的所占市场份额值
	 * @param color 在柱形图中所显示的颜色
	 */
	public Contact(String name, double value, String color) {
		this.name = name;
		this.value = value;
		this.color = color;
	}
	
	// 下面是三个实例变量的getters and setters
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public double getValue() {
		return value;
	}
	public void setValue(double value) {
		this.value = value;
	}
	public String getColor() {
		return color;
	}
	public void setColor(String color) {
		this.color = color;
	}
	
}

然后模拟http请求加载数据的过程:
package com.example.achartdemo.http;
import java.util.ArrayList;
import java.util.List;

import com.example.achartdemo.beans.Contact;

public class ContactService {

	public List<Contact> getContacts() {
		List<Contact> contacts = new ArrayList<Contact>();
		contacts.add(new Contact("IE", 32.85, "#a5c2d5"));
		contacts.add(new Contact("Chrome", 33.59, "#cbab4f"));
		contacts.add(new Contact("Firefox", 22.85, "#76a871"));
		contacts.add(new Contact("Safari", 7.39, "#9f7961"));
		contacts.add(new Contact("Opera", 1.63, "#a56f8f"));
		contacts.add(new Contact("Other", 1.69, "#6f83a5"));
		return contacts;
	}
}

定义界面展示的XML布局文件:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.achartdemo.MainActivity$PlaceholderFragment" >
    
    <WebView 
        android:id="@+id/webview"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

</RelativeLayout>

在Actitivy或者Fragment中加载布局并作View的初始化操作:
package com.example.achartdemo;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
import android.support.v7.app.ActionBarActivity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.WebSettings;
import android.webkit.WebView;

public class MainActivity extends ActionBarActivity {
	
	private static Context mContext;
	private static Handler mHandler = new Handler();

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		mContext = this;

		if (savedInstanceState == null) {
			getSupportFragmentManager().beginTransaction()
					.add(R.id.container, new PlaceholderFragment()).commit();
		}
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {

		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		// Handle action bar item clicks here. The action bar will
		// automatically handle clicks on the Home/Up button, so long
		// as you specify a parent activity in AndroidManifest.xml.
		int id = item.getItemId();
		if (id == R.id.action_settings) {
			return true;
		}
		return super.onOptionsItemSelected(item);
	}

	/**
	 * A placeholder fragment containing a simple view.
	 */
	public static class PlaceholderFragment extends Fragment {
		private WebView mWebView;

		public PlaceholderFragment() {
		}

		@Override
		public View onCreateView(LayoutInflater inflater, ViewGroup container,
				Bundle savedInstanceState) {
			View rootView = inflater.inflate(R.layout.fragment_main, container,
					false);
			initView(rootView);
			return rootView;
		}
		
		@SuppressLint({ "SetJavaScriptEnabled", "JavascriptInterface" })
		private void initView(View rootView) {
			mWebView = (WebView) rootView.findViewById(R.id.webview);
			mWebView.setHorizontalScrollBarEnabled(true);
			mWebView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
			WebSettings settings = mWebView.getSettings();
			settings.setDefaultTextEncodingName("UTF-8");
			settings.setJavaScriptEnabled(true);
			settings.setSupportZoom(true);
			settings.setBuiltInZoomControls(true);
			mWebView.addJavascriptInterface(new JSInterface(mContext, mHandler, mWebView), JSInterface.TAG);
			String url = "file:///android_asset/index.html";
			mWebView.loadUrl(url);
		}
	}

}

关键的代码是我们需要在WebView中展现的HTML页面,代码如下:
<!DOCTYPE html>
<html>
	<head>
		<meta charset="UTF-8" />
		<title>Hello World</title>
		<meta name="viewport" content="width=device-width, user-scalable=no" target-densitydpi="device-dpi"/>
		<meta name="Description" content="" />
		<meta name="Keywords" content="" />
		<script type="text/javascript" src="ichart.1.2.min.js"></script>
		<script type="text/javascript">
			var data = new Array();
			var contact = window.JSInterface.getContacts(); //得到JSInterface中转换出的json字符串
			eval('data='+contact); //得到json数据

			$(function(){	
				new iChart.Column3D({
					render : 'canvasDiv', //渲染的Dom目标,canvasDiv为Dom的ID
					data: data, //绑定数据
					title : 'Top 5 Browsers in August 2012', //设置标题
					showpercent:true, //显示百分比
					decimalsnum:2, 
					width : 600, //设置宽度,默认单位为px
					height : 300, //设置高度,默认单位为px
					align:'left',
					offsetx:50,
					animation : true,//开启过渡动画
					duration_animation_duration:800,//800ms完成动画 
					legend : {
						enable : true
					},
					coordinate:{ //配置自定义坐标轴
						scale:[{ //配置自定义值轴
							 width:600,
							 position:'left', //配置左值轴	
							 start_scale:0, //设置开始刻度为0
							 end_scale:40, //设置结束刻度为40
							 scale_space:8, //设置刻度间距为8
							 listeners:{ //配置事件
								parseText:function(t,x,y){ //设置解析值轴文本
									return {text:t+"%"}
								}
							}
						}]
					}
				}).draw(); //调用绘图方法开始绘图
			});
		</script>
	</head>

	<body>
		<div id='canvasDiv'></div>
	</body>
</html>

刚才在Activity中引用的JSInterface类,是我们用来跟HTML页面进行数据交互的JS接口类,代码如下:
package com.example.achartdemo;

import java.util.List;
import java.util.Random;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.content.Context;
import android.os.Handler;
import android.util.Log;
import android.webkit.WebView;
import android.widget.Toast;

import com.example.achartdemo.beans.Contact;
import com.example.achartdemo.http.ContactService;

public class JSInterface {
	public static final String TAG = JSInterface.class.getSimpleName();
	private Context		mContext	= null;
	private Handler		mHandler	= null;
	private WebView		mView;

	private JSONArray	jsonArray	= new JSONArray();
	private Random		random		= new Random();

	public JSInterface(Context context, Handler handler, WebView webView) {
		mContext = context;
		mHandler = handler;
		mView = webView;
	}

	public void init() {
		// 通过handler来确保init方法的执行在主线程中
		mHandler.post(new Runnable() {

			public void run() {
				// 调用网页setContactInfo方法
				mView.loadUrl("javascript:setContactInfo('" + getJsonStr() + "')");
			}
		});
	}

	public int getW() {
		return px2dip(mContext.getResources().getDisplayMetrics().widthPixels);
	}

	public int getH() {
		return px2dip(mContext.getResources().getDisplayMetrics().heightPixels);
	}

	public int px2dip(float pxValue) {
		final float scale = mContext.getResources().getDisplayMetrics().density;
		return (int) (pxValue / scale + 0.5f);
	}

	public void setValue(String name, String value) {
		Toast.makeText(mContext, name+" "+value+"%", Toast.LENGTH_SHORT).show();
	}

	@SuppressLint("DefaultLocale")
	public String getRandColorCode() {
		String r, g, b;
		Random random = new Random();
		r = Integer.toHexString(random.nextInt(256)).toUpperCase();
		g = Integer.toHexString(random.nextInt(256)).toUpperCase();
		b = Integer.toHexString(random.nextInt(256)).toUpperCase();

		r = r.length() == 1 ? "0" + r : r;
		g = g.length() == 1 ? "0" + g : g;
		b = b.length() == 1 ? "0" + b : b;

		return "#" + r + g + b;
	}

	public String getJsonStr() {
		try {

			for (int i = 0; i < 10; i++) {
				JSONObject object1 = new JSONObject();
				object1.put("name", "name" + i);
				object1.put("value", random.nextInt(30));
				object1.put("color", getRandColorCode());
				jsonArray.put(object1);
			}
			Log.i("", jsonArray.toString());
			return jsonArray.toString();
		} catch (JSONException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	/** 
     * 实现将list转换成json格式字符串 
     * @return json格式的字符串 
     */  
    public String getContacts() {  
    	ContactService contactService = new ContactService();
        List<Contact> contacts = contactService.getContacts();  
        String json = null;  
        try {  
            JSONArray array = new JSONArray();  
            for (Contact contact : contacts) {  
  
                JSONObject item = new JSONObject();  
                item.put("name", contact.getName());  
                item.put("value", contact.getValue());  
                item.put("color", contact.getColor());  
                array.put(item);  
            }  
            json = array.toString();  
            Log.i(TAG, json);  
        } catch (JSONException e) {  
            e.printStackTrace();  
        }  
        return json;  
    } 
}

上述的代码片段即可组合成一个工程,编译运行了。当然,我们需要把ichartjs的JS库和写好的HTML页面引入到我们工程目录下的assets文件夹下。另外,有一个需要注意的地方,我们在定义3D柱状图的时候,配置了柱状图的展示动画,需要在AndroidMenifest.xml文件中配置应用可以开启硬件加速:
<application
        android:hardwareAccelerated="true"
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name="com.example.achartdemo.MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

下面附上运行的效果图:

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值