本文是关于 Android 图表实现的一个实践笔记。简单封装百度的 ECharts,轻松实现各种图表效果。
相关 Github 源码 • Charts
版权声明:本文为 frendy 原创文章,可以随意转载,但请务必在明确位置注明出处。
其实目前已经有一些相关的开源项目,例如 MPAndroidChart 、hellocharts-android 、XCL-Charts 等等,但是呢...对于笔者的项目而言,它们远远不够丰富啊。
于是,在综合权衡项目进度、Android 和 iOS 两端的开发成本以及用户体验之后,笔者选择了在 ECharts 的基础上来实现图表。ECharts 基于 Js 实现,如下图所示,各种图表是不是丰富多彩,必须为 ECharts 的贡献者们点个赞。
好的,路选好了,其实本质上也就是用 WebView 加载本地 H5。嗯,走起来,发现其实也不难,ECharts 里各种图表的属性和数据等都是由 option 决定,因此可以考虑以下两个方向:
- 由 Android 获取数据并生成 option,而 H5 则负责解析 option 并调用 ECharts 进行绘制;
- H5 负责所有流程,获取数据、生成 option并调用 ECharts 进行绘制。
基于上面两个思考,笔者封装了 EChartView 来实现,源码可参考 Charts,基于 Kotlin 实现,为什么用 Kotlin?除了最近用习惯了不再想用 Java 外,还有一个更重要的原因,这里请允许 frendy 卖个关子先,文章后面再做解释吧。
嗯,目前 Demo 效果如下图示,后面也会随着项目的开发做进一步完善:
方向 1:由 Android 获取数据并生成 option,而 H5 则负责解析 option 并调用 ECharts 进行绘制。
然而,在 ECharts 里 option 各种属性,那么多那么细,怎么操作?其实,已经有前人栽树 abel533 • ECharts,进一步封装交互细节即可。如下面的代码所示,其实写起来还是挺麻烦的,需要参考 js 的 option 实现一个个翻译。
恩,这个痛点就是 frendy 决定用 Kotlin 的原因了,可以考虑将这棵前人栽的树重新封装成自己的 DSL (Domain-Specific Language),这样就可以像 js 一样声明式编程了。当然,这个 DSL 封装目前还只是计划,后面有空整起来,也欢迎有兴趣的朋友一起贡献完善,相关Github 项目地址 Charts。
chartView.setType(1)
chartView.setDataSource(this)
override fun markChartOptions(): GsonOption {
return getPieChartOptions()
}
fun getPieChartOptions(): GsonOption {
val option = GsonOption()
option.tooltip().trigger(Trigger.item).formatter("{a}
{b} : {c} ({d}%)")
option.legend().data("直接访问", "邮件营销", "联盟广告", "视频广告", "搜索引擎");
val pie = getPie().center("50%", "45%").radius("50%")
pie.label().normal().show(true).formatter("{b}{c}({d}%)")
option.series(pie)
return option
}
fun getPie(): Pie {
return Pie().name("访问来源").data(
PieData("直接访问", 335),
PieData("邮件营销", 310),
PieData("联盟广告", 274),
PieData("视频广告", 235),
PieData("搜索引擎", 400))
}
var option = JSON.parse(Android.getChartOptions());
chart.setOption(option);
方向 2:H5 负责所有流程,获取数据、生成 option并调用 ECharts 进行绘制。
至于这个混合开发的方向,其实在 Android 端也不需要做太多开发了,主要工作量在于完善本地 H5 模板及相关交互、优化加载流程以提升用户体验等。这个方向有一个好处还是很明显的,一次开发三端(Web / Android / iOS)都可以使用。
chartView.loadUrl("file:///android_asset/echart/biz/map.html")
function load() {
option = {
title: {
text: 'iphone销量',
subtext: '纯属虚构',
left: 'center'
},
tooltip: {
trigger: 'item'
},
legend: {
orient: 'vertical',
left: 'left',
data:['iphone3','iphone4','iphone5']
},
visualMap: {
min: 0,
max: 2500,
left: 'left',
top: 'bottom',
text: ['高','低'], // 文本,默认为数值文本
calculable: true
},
toolbox: {
show: true,
orient: 'vertical',
left: 'right',
top: 'center',
feature: {
dataView: {readOnly: false},
restore: {},
saveAsImage: {}
}
},
series: [
...
]
};
chart.setOption(option);
}
好了,在文章最后还是贴一下这个库的引用方法吧,后续随着项目开发 frendy 再做进一步完善:
- 在根目录的 build.gradle 添加以下 repositories:
allprojects {
repositories {
...
maven { url 'https://jitpack.io' }
}
}
- 添加依赖如下:
dependencies {
compile 'com.github.frendyxzc:Charts:0.0.2'
}