本文已参与「新人创作礼」活动,一起开启掘金创作之路。
做Android开发经常会需要画一些图表,自己写的话不仅麻烦而且工作量太大,所以一般都会采用第三方图表框架 ,这时候就用到了ECharts
前言
ECharts 是由百度开发提供的开源框架,主要提供给Web使用,所以Android中一般使用WebView加载显示,其实本质上也就是用 WebView 加载本地 H5。 ECharts的图表样式主要由option控制,option是由js编写,如下面代码就是一个简单折线图的option。
在andorid中使用ECharts,一般来讲我们有两种实现方案
- Android获取数据并封装好option,然后传递给h5,h5再对数据进行解析,调用ECharts绘制。 这种方案的难点在于option的属性太多了,封装起来太麻烦。
- h5处理所有操作,进行获取数据,并调用ECharts进行绘制。 这种方案需要对js比较熟悉。
以第一种为例: 下载自定义图表
-
将下载好的echarts.min.js文件放入工程中assets目录下。
-
编写healthy.html文件,并将healthy.html放入assets目录。
(或者直接输入healthy.html)
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<!-- 引入 ECharts 文件 -->
<script src="echarts.min.js"></script>
</head>
<body>
<!-- 为 ECharts 准备一个具备大小(宽高)的 DOM -->
<div id="main" style="height: 244px;"></div>
<script type="text/javascript">
var myChart1 = echarts.init(document.getElementById('main'));
var option;
option = {
title: {
text: "工单数波形图",
textStyle: {
color: "#2DC3FB",
fontWeight: "bold",
fontSize: "16",
},
padding: [20, 0, 0, 0],
},
tooltip: {
backgroundColor: "#31516B",
opacity: 0.3,
trigger: "axis",
axisPointer: { // 焦点处样式
type: "cross",
},
extraCssText: "text-align: center;",
//在这里设置
formatter: "{b0}<br/>{c0}个",
textStyle: {
color: "rgba(145, 201, 246, 1)",
},
},
legend: {
data: ["总工单", "未完成工单"],
textStyle: {
color: "#738CA0",
},
itemWidth: 10,
itemHeight: 10,
icon: "rect",
right: 16,
top: 16,
},
grid: {
left: "3%",
right: "4%",
bottom: "3%",
containLabel: true,
},
xAxis: {
type: "category",
axisTick: {
show: false,
},
axisLabel: {
color: "#20dbfd",
},
axisLine: {
lineStyle: {
color: "#20dbfd",
},
},
data: ["07-11", "07-12", "07-13", "07-14", "07-15", "07-16", "07-17"],
},
yAxis: {
type: "value",
min: 0,
max: 100,
axisTick: {
show: false,
},
axisLabel: {
// 折线下方阴影
color: "#20dbfd",
},
axisLine: {
// 坐标轴线
lineStyle: {
color: "#20dbfd",
},
},
splitLine: {
// y轴 辅助线
show: false,
},
},
series: [
{
name: "总工单",
type: "line",
smooth: false,
stack: "总工单",
symbol: "circle", // 拐点为实心的 默认为空心
itemStyle: {
color: "#72F5FF",
},
lineStyle: {
shadowBlur: 5,
color: "#17D5E3",
shadow: "0px 5px 1px 0px rgba(0, 0, 0, 0.41)",
},
areaStyle: {
opacity: 0.5,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(13, 182, 252, 0.5)",
},
{
offset: 1,
color: "rgba(13, 182, 252, 0)",
},
]),
},
data: [30, 26, 60, 67, 50, 80, 37],
},
{
name: "未完成工单",
type: "line",
smooth: false,
stack: "未完成工单",
symbol: "circle", // 拐点为实心的 默认为空心
itemStyle: {
color: "#ff3f68",
},
lineStyle: {
shadowBlur: 5,
color: "#E74867",
shadow: "0px 5px 1px 0px rgba(0, 0, 0, 0.41)",
},
areaStyle: {
opacity: 0.5,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: "rgba(231, 72, 103, 0.5)",
},
{
offset: 1,
color: "rgba(231, 72, 103, 0)",
},
]),
},
data: [10, 6, 37, 25, 30, 8, 16],
},
],
};
//先初始化默认的echarts图 ,setData() 这个方法是来接收需要改变echarts图的地方
myChart1.setOption(option);
function setData(option) {
// 基于准备好的dom,初始化echarts实例
var myChart = echarts.init(document.getElementById('main'));
// 使用刚指定的配置项和数据显示图表。
myChart.setOption(option);
}
</script>
</body>
</html>
-
第一种方法 :简单的使用
activity_main.xml
<WebView
android:id="@+id/orderrcharts_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
MainActivity.kt
==(kotlin写法)==
//设置webview透明
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null)
webView.setBackgroundColor(0)
//开启本地文件读取(默认为true,不设置也可以)
webView.settings.allowFileAccess = true
//开启脚本支持
webView.settings.javaScriptEnabled = true
webView.loadUrl("file:///android_asset/healthy.html")
==(Java写法)==
WebView webView=findViewById(R.id.webview);
webView.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
webView.setBackgroundColor(0);
//开启本地文件读取(默认为true,不设置也可以)
webView.getSettings().setAllowFileAccess(true);
//开启脚本支持
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("file:///android_asset/healthy.html");
-
第二种方法 :
activity_main.xml
<com.board.utils.HtEChartView
android:id="@+id/orderrcharts_main"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
MainActivity.kt ==(kotlin写法)==
// y,x 是横坐标和纵坐标的值
surgarHightBlood_main.setData2(y, x)
-
获取值 动态的给图赋值
public class HtEChartView extends LinearLayout {
private WebView webView;
private boolean isScrollEnabled = true;
public HtEChartView(Context context) {
this(context, null);
}
public HtEChartView(Context context, @Nullable AttributeSet attrs) {
this(context, attrs, 0);
}
public HtEChartView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
initView(context);
}
@SuppressLint({"SetJavaScriptEnabled", "ClickableViewAccessibility"})
private void initView(Context context) {
LayoutInflater layoutInflater = LayoutInflater.from(context);
if (layoutInflater == null) {
return;
}
View view =layoutInflater.inflate(R.layout.activity_ht_echart, this);
webView = view.findViewById(R.id.web_view_id);
webView.getSettings().setJavaScriptEnabled(true);
webView.setScrollContainer(false);
webView.setVerticalScrollBarEnabled(false);
webView.setHorizontalScrollBarEnabled(false);
}
/**
* 绑定数据 健康指数
* @param ydata
* @param xdata
*/
public void setData2(ArrayList<Double> ydata, ArrayList<String> xdata) {
if (webView == null) {
return;
}
webView.setWebViewClient(new HtWebViewClient(ydata,xdata));
webView.loadUrl("file:///android_asset/healthy.html");
}
}
-
HtWebViewClient
public class HtWebViewClient extends WebViewClient {
private ArrayList<Double> ydata;
private ArrayList<String> xdata;
public HtWebViewClient(ArrayList<Double> ydata, ArrayList<String> xdata) {
this.ydata=ydata;
this.xdata=xdata;
}
@Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
@Override
public void onPageFinished(final WebView view, String url) {
super.onPageFinished(view, url);
view.post(new Runnable() {
@Override
public void run() {
//设置webview透明
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
view.setBackgroundColor(0);
//开启本地文件读取(默认为true,不设置也可以)
view.getSettings().setAllowFileAccess(true);
//把穿过来的值 ,转换成字符串
String dataX="[";
String dataY="[";
for(int i=0;i<xdata.size();i++){
if(i<xdata.size()-1){
dataX=dataX+"\""+xdata.get(i)+"\",";
dataY=dataY+"\""+ydata.get(i)+"\",";
}else{
dataX=dataX+"\""+xdata.get(i)+"\"]";
dataY=dataY+"\""+ydata.get(i)+"\"]";
}
}
//取出最小值
double min= ydata.get(0);
for (int i=1;i<ydata.size()-1;i++){
if (min> ydata.get(i)){
min= ydata.get(i);
}
}
min-=0.2;
String result = String.format("%3.2f", min);
//这是需要显示的数值
String option=" {\n" +
" \"xAxis\": {\n" +
" \"data\": " +dataX+ ", \n" +
" },\n" +
" \"yAxis\": {\n"+
" \"min\":"+result+",\n"+
" },\n"+
" \"series\": [\n" +
" {\n" +
" \"data\":" +dataY+ "\n" +
" }\n" +
"], \n" +
" }";
view.loadUrl(String.format("javascript:setData(%s)", option));
}
});
}
@Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
}
}