该开源库可完成线形图、柱状图、饼状图等等,具体显示效果可参考下图:
以上是一些图片效果展示,具体更多的例子和信息,可以直接看官网:
https://github.com/lecho/hellocharts-android
这里将hellocharts开源库集成到自己的项目中,有如下3中方法
dependencies{
compile 'com.github.lecho:hellocharts-library:1.5.8@aar'
}
2 在app下的lib文件夹中添加 jar包,同步到项目中即可,多适用于Eclipse(获取jar包网址如下)
https://github.com/lecho/hellocharts-android/releases
3 去github上下载Demo源码,其中有依赖的Library,添加module到项目中。
第一种和第二种类型相同,导入比较简单,但是定制性不高!个人比较推荐第三种,导入Library到自己项目中,后续可根据自己特殊要求修改源码,但是我在导入时出现了一些问题,下面详细讲解一下问题和解决方法。
(1). 在AS项目中import添加module(也就是hellocharts-library)进来,AS会自动开始编译,于是第一个错误出现:
(2). 打开hellocharts-library的build.gradle文件,恍然大悟, 由于这个Library是官网提供的demo里面的,所以一些配置写的是特定常量数值,而导入我们的项目后并不能识别出来,所以修改即可,如下图:
这里可以看出,参考项目中app下的build.gradle文件,将编译版本、sdk版本换成自己本地的即可,然后还有一些版本号、版本名字,这些不是太重要,随便填即可。(我写的是1)然后再次编译。
(3). 编译完成后,异常再次出现:
这个错误在导入github上的library时经常出现,原因就是
library has gradle tasks for uploading to the Maven repository that require some properties to be set for the gradle environment, in your project you don’t need/want that.
library中的gradle会加载Maven 库,所以它要求在gradle环境中设置一些属性。(若对gradle不熟悉的无须深究)而解决方法就是找到library的build.gradle中的apply引用,将apply关键词后是 from 的引用去掉即可。
再次编译,即可成功,亲测有效。总结来说,在导入library时,需要修改library中的build.gradle文件,主要修改为:修改常量配置为app配置 和 去掉不必要gradle属性。
关于Demo,官网其实给出的例子很详细,但是仔细看下来注释非常少,着实有些晦涩难懂,特别是初学者,所以这里我建议一个网址,这位coder自己改写了demo,更是直接译成了中文版,福音~
中文版介绍官方例子
废话不多说,先上效果图,如上所示。既然是新手教学,那么首先要完成最基本的柱状图显示:
直接使用对应的控件,代码如下
.lib.hellocharts.view.ColumnChartView
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="400dp"
android:layout_margin="10dp"/>
/*========== 数据相关 ==========*/
private ColumnChartData mColumnChartData; //柱状图数据
在介绍之前先重点提一个类ColumnChartData ,查看这个类的字面意思可知ColumnChartData中含有所有与柱状图有关的数据,其中不管是柱子列表的值,还是坐标抽的有关设置,总之,所有柱状图的设置都包含其中。试想,当我们将这个类的数据都填充好后,最后只需将数据设置到view中,大功即可告成,而现在的工作就是开始填充ColumnChartData:
既然是柱体列表,那么一定是ArrayList,主要是柱体数据这个类的认知,此类是Column,官方介绍是
Single column for ColumnChart. One column can be divided into multiple sub-columns(ColumnValues) especially for
stacked ColumnChart.
大意为:Column是柱状图的一个单列,而且一个单列柱体Column可以被分成多个子柱体SubcolumnValue。查看Column类内部源码可知,一个Column对象也是由SubcolumnValue列表组成。对比示意图如下:
经过上面的图文讲解后,得知在创建Column对象时,我们先要填充它的子柱体SubcolumnValue。之所以这样设计也是为了满足各式的需求,但是我这里的需求暂时不涉及到子列,所以实现方法为上图第二种,代码如下:
/*========== 柱状图数据填充 ==========*/
List columnList = new ArrayList<>(); //柱子列表
List subcolumnValueList; //子柱列表(即一个柱子,因为一个柱子可分为多个子柱)
for (int i = 0; i < 7; ++i) {
subcolumnValueList = new ArrayList<>();
subcolumnValueList.add(new SubcolumnValue((float) Math.random() * 50f, ChartUtils.pickColor()));
Column column = new Column(subcolumnValueList);
columnList.add(column);
}
mColumnChartData = new ColumnChartData(columnList); //设置数据
最后填充好柱体列表columnList,回想我一开始所说的,柱状图所有有关数据存放到ColumnChartData类,也就是以上代码最后一句,此时,柱体列表数据填充完毕。
往ColumnChartData类放置了柱体列表数据后,需要设置好坐标轴数据,比较简单,配有注释,看代码即可:
/*===== 坐标轴相关设置 =====*/
Axis axisX = new Axis();
Axis axisY = new Axis().setHasLines(true);
axisX.setName("Axis X"); //设置横轴名称
axisY.setName("Axis Y"); //设置竖轴名称
mColumnChartData.setAxisXBottom(axisX); //设置横轴
mColumnChartData.setAxisYLeft(axisY); //设置竖轴
//以上所有设置的数据、坐标配置都已存放到mColumnChartData中,接下来给mColumnChartView设置这些配置
mColumnChartView.setColumnChartData(mColumnChartData);
以上完成后,恭喜你,新手教学成功,可以将程序跑到手机上,而效果就是我一开始展示的那样,简单的柱状图和坐标显示。突然,PM来了,看着这张图不禁陷入了沉思,效果还行,可是达不到我理想的需求啊。
PM:你这不行…….
android程序猿:这不挺好看的吗,红红绿绿的
PM:首先啊,你这坐标名不符合实际,得改!横轴下的名称1.2.3.4谁看的懂啊,得改!这竖轴的最大值怎么是39?这学生成绩最高应该是100,得改!
android程序猿:恩…..似乎有些道理,第一:坐标名上面的代码已经提到过了,就是一个setName,简单!第二:需要修改横坐标的显示值,那么需要一组ArrayList设置横坐标值,应该不难。第三:可以看出,竖轴最大值是根据我们设置的值,选取最大的作为竖轴最大值,确实有些不妥,这里设置一下竖轴最大值即可。好了,我去修改
PM:等会,还没说完,虽然这个柱状图显示效果不错,但是每个柱体代表的具体数值最好能显示出来,更加精确。
android程序猿:恩…..就是给每个柱体设置列标签,显示具体数值。了解了,再见
PM:诶诶诶,别走啊,还没说完呢。柱体标签实现好后,虽然起到了一个显示的效果,但是交互方面并不达标,用户肯定会点击相关的柱体,这是需要在界面上显示具体的数据。
android程序猿:简单,这不就是平常我们给View设置Click监听吗?虽然方法不同,但是性质是一样的,然后………(我睁开卡姿兰大眼睛45度角深情地望着PM的双下巴)
PM:好的,诶,你怎么还不去修改啊?
android程序猿:我…….以为你还有需求
PM:哎哟,还想我提,那我说啦
android程序猿:别别别,今天还想早点下班呢,下班一起吃饭去啊,走了走了
撸起袖子开始干!
根据以上程序猿和PM愉快的交流,咳咳,我们来实现需求吧…….
关于自定义横轴显示值列表,官方在介绍Column柱体类的时候已经说明:
Note: you can set X value for columns or sub-columns, columns are by default indexed from 0 to numOfColumns-1
column index is used as column X value, so first column has X value 0, second clumn has X value 1 etc.
If you want to display AxisValue for given column you should initialize AxisValue with X value of that column.
大意是说横轴的显示值默认是从 0 ~ 柱体总数-1,如果你想使用自定义的横轴显示值,需要定义AxisValue集合,而这个类定义为轴,通常设置时需要结合其位置,所以最好在设置柱体列表值的循环中去处理:
public final static String[] xValues = new String[]{"语文", "数学", "英语", "音乐", "科学", "体育"};
/*========== 柱状图数据填充 ==========*/
List columnList = new ArrayList<>(); //柱子列表
List subcolumnValueList; //子柱列表(即一个柱子,因为一个柱子可分为多个子柱)
List axisValues = new ArrayList<>();//自定义横轴坐标值
for (int i = 0; i < xValues.length; ++i) {
subcolumnValueList = new ArrayList<>();
subcolumnValueList.add(new SubcolumnValue((float) Math.random() * 100f, ChartUtils.pickColor()));
Column column = new Column(subcolumnValueList);
columnList.add(column);
//设置坐标值
axisValues.add(new AxisValue(i).setLabel(xValues[i]));
}
......
//将自定义x轴显示值传入构造函数
Axis axisX = new Axis(axisValues);
同柱体列表数据填充一样,获得填充好的axisValues集合,需要设置给相关轴,由于这是横轴,所以在创建new横轴时,需要将数据传递给构造函数。
介绍之前我又要提到一个重要的类Viewport,定义如下:
Partial copy of android.graphics.Rect but here the top should be greater then the bottom. Viewport holds 4 float
coordinates for a chart extremes. The viewport is represented by the coordinates of its 4 edges (left, top, right,bottom).These fields can be accessed directly. Use width() and height() to retrieve the viewport’s width and height.
大意是Viewport类copy了android.graphics.Rect一部分,相当于一个矩形,但是这里特别需要注意的是它的高必须大于底,右要大于左,可由四个边的坐标(左,上,下,右)表示,这些字段可以直接访问。 使用width()和height()来检索视口的宽度和高度。
通俗的讲,就把它当成这个图表的外框,而这跟设置竖轴最大值有什么干系呢?我的理解是:它有点类似于View,在柱状图数据设置好给mColumnChartView之后(此时,柱状图可以正常展示了),我们可以获取到Viewport的引用,因为mColumnChartView就是装载在Viewport里,然后修改它的top也就是竖轴最大值(当然其余值也可以修改,暂时需求不涉及),这样是否与View有点相似?
//法一:
Viewport v = mColumnChartView.getMaximumViewport();
v.top = 100;
mColumnChartView.setCurrentViewport(v);
//法二:
Viewport v = mColumnChartView.getCurrentViewport();
v.top = 100;
mColumnChartView.setMaximumViewport(v);
mColumnChartView.setCurrentViewport(v);
以上则是实现代码,是不是简单到吐血?但是摸索的过程是相反的…..
(tips : 我发现设置100,他显示了最大,但100数值为出现,好像上部分被遮挡住了几个像素?不是很清楚,所以设置成103,比理想值稍大一点,效果可以完美显示)
/*===== 坐标轴相关设置 =====*/
Axis axisX = new Axis(); //将自定义x轴显示值传入构造函数
Axis axisY = new Axis().setHasLines(true); //setHasLines是设置线条
axisX.setName("Axis X"); //设置横轴名称
axisY.setName("Axis Y"); //设置竖轴名称
mColumnChartData.setAxisXBottom(null);
mColumnChartData.setAxisYLeft(null);
给每个柱体设置列标签 setHasLabels(true)
这个需求我们还是放到填充柱体数据的循环里去完成,在每次创建填充好单个 Column柱体对象后,给它设置属性setHasLabels(true)即可,代码如下:
/*========== 柱状图数据填充 ==========*/
List columnList = new ArrayList<>(); //柱子列表
List subcolumnValueList; //子柱列表(即一个柱子,因为一个柱子可分为多个子柱)
List axisValues = new ArrayList<>();
for (int i = 0; i < xValues.length; ++i) {
subcolumnValueList = new ArrayList<>();
subcolumnValueList.add(new SubcolumnValue((float) Math.random() * 100f, ChartUtils.pickColor()));
Column column = new Column(subcolumnValueList);
columnList.add(column);
column.setHasLabels(true);//☆☆☆☆☆设置列标签
//设置坐标值
axisValues.add(new AxisValue(i).setLabel(xValues[i]));
}
//只有当点击时才显示列标签
column.setHasLabelsOnlyForSelected(true);
同其它View设置监听没什么不同,给View设置监听方法为setOnValueTouchListener
,值得注意的是这里实现ColumnChartOnValueSelectListener
只为View提供了两种状态时可进行的操作,那就是点击 和 未点击。而这里我的实现需求只是在点击时Toast对应柱体的值,各位也可以在其中实现更完美的效果,代码如下:
mColumnChartView.setOnValueTouchListener(new ValueTouchListener());
private class ValueTouchListener implements ColumnChartOnValueSelectListener {
@Override
public void onValueSelected(int columnIndex, int subcolumnIndex, SubcolumnValue value) {
Toast.makeText(ColumnActivity.this, xValues[columnIndex]+"成绩 : " +
(int)value.getValue(),Toast.LENGTH_SHORT).show();
}
@Override
public void onValueDeselected() {
// TODO Auto-generated method stub
}
}
根据以上的花式教学,可以看出柱状体使用其实并不难,只是涉及到许多类的联系,初次学习确实有些晦涩难懂,在此将涉及到的类做一个简单的总结:
类名 | 大致介绍 |
---|---|
ColumnChartData | 控制柱状图的数据模型,有关数据、坐标等相关配置都涉及到此类 |
Column | 柱状图中单个柱体类 |
SubcolumnValue | 柱状图中单个子柱体类(一个柱体由多个子柱体组成) |
Axis | 单个坐标模型(如横坐标、竖坐标) |
AxisValue | 单个坐标的值(其中包含坐标分布的名称、标签) |
Viewport | 相当于图表的外壳,里面包含有柱状图,可以获取图表top、bottom、left、right值和长、宽度等等 |
github原作者提供的demo初次学习确实有些困难,包括以上我对涉及类的解释,都是查看的代码注释。所以对学习此开源库的friends分享一个学习方法:
以上涵盖了柱状图开发的大部分讲解,当然,它的功能还不止这些,有些什么反向子列、堆叠效果等等,但是跟我的需求没什么联系,在这里不做太多介绍,有兴趣的可以去看官方demo。
以上所有代码实现都已包含在demo中,另外demo中有个package包,里面包含的是官方demo中的柱状图演示部分(此部分来源于iamxiarui博客,有改写官方demo,中文版且注释很多,多谢分享~),可结合查看
就酱~
最后效果图如下:
最后PM露出满意的微笑,搂着android程序猿吃饭去啦…….haha~~
以上教程够花式了吧,初次尝试以程序猿和PM对话来确定需求和功能实现,这种对话模式自己写起来觉得很有趣,haha(并无黑PM的含义)
上面内容弄懂后,满足一般的柱状图需求没有什么大问题,完结撒花~
以上演示代码在此:
https://github.com/gnemyg7221/HelloChartsDemo/tree/master
希望对你们有帮助 :)