开始
添加依赖
在第一步,需要将依赖的库添加到你的项目中
创建View
想要使用 LineChart,BarChart,ScatterChart,CandleStickChart,PieChart,BubbleChart或者RadarChart,需要先在xml中定义
然后在你的Activity或者Fragment中获取控件
LineChart chart = (LineChart) findViewById(R.id.chart);
或者使用代码创建,在布局中添加
LineChart chart = new LineChart(Context);
RelativeLayout rl = (RelativeLayout) findViewById(R.id.relativeLayout);
rl.add(chart);
添加数据
在你拥有了图表的实例之后,你可以创建数据并添加到图表中.下面是一个使用折线图的例子,每一条数据都可以使用Entry这个类来标识x,y坐标.
在其他图表类型中,比如BarChart使用其他的类(比如BarEntry)来达到相同的目的.
添加数据到图表中,需要将所有的数据都包裹在Entry对象中
YourData[] dataObjects = ...;
List entries = new ArrayList();
for (YourData data : dataObjects) {
entries.add(new Entry(data.getValueX(), data.getValueY()));
}
然后,你需要给你创建的LineDataSet对象添加List
下面的"Label"用于描述数据的作用,如果图例开启的话,还会作为图例显示在图表上
LineDataSet dataSet = new LineDataSet(entries, "Label"); // 添加数据
dataSet.setColor(...);
dataSet.setValueTextColor(...); // 自定义数据样式
最后一步,你需要把创建好的LineDataSet添加到LineData中,添加完数据,利用Chart的实例去设置数据,并且刷新一下
LineData lineData = new LineData(dataSet);
chart.setData(lineData);
chart.invalidate(); // 刷新
图表的交互
这个库可以让你最大限度的通过手势触摸与图表交互,并且通过回调函数获取反馈
开启/关闭交互
- setTouchEnabled(boolean enabled): 允许触摸图表
- setDragEnabled(boolean enabled): 允许拖拽图表
- setScaleEnabled(boolean enabled): 允许缩放图表
- setScaleXEnabled(boolean enabled): 允许以X轴缩放
- setScaleYEnabled(boolean enabled): 允许以Y轴缩放
- setPinchZoom(boolean enabled): 如果为true则x和y轴将会联动缩放,否则就分开缩放
- setDoubleTapToZoomEnabled(boolean enabled): 若允许则可以双击进行缩放
图表滑动
- setDragDecelerationEnabled(boolean enabled): 设置为true,图表在手指触碰滑动后,会有惯性继续运动
- setDragDecelerationFrictionCoef(float coef): 设置一个在[0,1]区间内的滑动系数,越高的值代表减速会越慢,比如设置为0,在手指滑动图表离开后将会立即停止滑动,1是一个不规范的值,它将会被自动设置为0.9999
手势操作回调
如果使用手势操作图表,可以使用OnChartGestureListener来监听回调
public interface OnChartGestureListener {
//当手指刚触摸到图表时触发,action_down
void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture);
//当手指在图表上操作结束时调用,action_up、action_cancel
void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture);
//长按图表回调
public void onChartLongPressed(MotionEvent me);
//双击图表回调
public void onChartDoubleTapped(MotionEvent me);
//单击图表回调
public void onChartSingleTapped(MotionEvent me);
//滑动图表回调
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY);
//缩放图表回调
public void onChartScale(MotionEvent me, float scaleX, float scaleY);
//拖拽图表回调
public void onChartTranslate(MotionEvent me, float dX, float dY);
}
将你的Chart去设置手势监听器就可以实现这些回调
chart.setOnChartGestureListener(this);
高亮显示
开启/关闭高亮
- setHighlightPerDragEnabled(boolean enabled): 设置为true时,在图表完全缩小的情况下,拖拽图表可以高亮,默认为true
- setHighlightPerTapEnabled(boolean enabled): 设置为false时,图表将不会因为手势而高亮,拖拽和代码操作依旧可以触发高亮,默认为true
- setMaxHighlightDistance(float distanceDp): 设置触发可以高亮的最远距离,触摸点离图表过远时,将不会触发高亮
高亮样式可以由个人自定义
dataSet.setHighlightEnabled(true); // 是否允许高亮
dataSet.setDrawHighlightIndicators(true); // 设置是否有拖拽高亮指示器
dataSet.setHighlightColor(Color.BLACK); // 设置高亮颜色
代码高亮数据
- highlightValue(float x, int dataSetIndex, boolean callListener): 通过给的在dataset中的x位置,去高亮数据.dataSetIndex给-1时,将会禁止一切高亮,布尔值的callListener标识是否允许监听回调
- highlightValue(Highlight high, boolean callListener): 通过传递来的Highlight对象去高亮数据,hightlight对象传null时表示不高亮,布尔值的callListener标识是否允许监听回调
- highlightValues(Highlight[] highs): 传入一个Highlight[]数组以同时高亮多个条目,数组为空或者null时表示不进行高亮
- getHighlighted(): 返回一个Highlight[]数组,里面包含高亮的条目,x轴位置以及在dataset中的位置
选择回调
OnChartValueSelectedListener,通过触摸高亮数据时的回调
public interface OnChartValueSelectedListener {
//当图表内的一项被选中时的回调
public void onValueSelected(Entry e, Highlight h);
//当没有选择项时的回调
public void onNothingSelected();
}
Highlight类
Highlight类,通常被用于获取高亮条目的信息,或者用来给图表或者Entry对提供数据用于高亮,Highlight类提供两个构造函数
//标准的Highlight构造函数
public Highlight(float x, int dataSetIndex) { ... }
//给BarEntry使用的Highlight构造函数
public Highlight(float x, int dataSetIndex, int stackIndex) { ... }
一个通过代码方式利用Highlight进行高亮的例子
// highlight the entry and x-position 50 in the first (0) DataSet
Highlight highlight = new Highlight(50f, 0);
chart.highlightValue(highlight, false); // highlight this value, don't call listener
自定义高亮
所有用户输入的手势高亮形式都是由默认的ChartHighlighter类完成的,通过自定义ChartHighlighter类的实现来替换默认的,完成更多的不同的高亮形式
setHighlighter(ChartHighlighter highlighter): 传入自定义的ChartHighlighter实现类对象来完成高亮样式的设置
坐标轴
坐标轴类通过以下部分实现具体的样式
- Label 绘制在坐标轴旁,包含坐标轴的详细数据
- axis-line 坐标轴线
- grid-lines 横向的表格线
- LimitLines 限制线用于呈现一些特殊的信息,像边界、约束等
控制坐标轴的哪些部分可以被绘制
- setEnabled(boolean enabled): 坐标轴开关,设置为false时,不论其他设置怎样都不会再绘制坐标轴
- setDrawLabels(boolean enabled): 坐标值开关,设置为false时将不会绘制坐标值
- setDrawAxisLine(boolean enabled): 坐标线开关,设置为false时将不会绘制坐标线
- setDrawGridLines(boolean enabled): 表格背景线开关,设置为false时将不会绘制图表背景上的表格线
定制坐标轴的范围(最小/最大)
- setAxisMaximum(float max): 设置坐标轴的最大值,一旦设置将不会再自动按照提供的值进行计算
- resetAxisMaximum(): 恢复默认设置,自己设置的最大值将不再生效,仍有提供的数据进行自动计算得到
- setAxisMinimum(float min): 设置坐标轴的最小值,一旦设置将不会再自动按照提供的值进行计算
- resetAxisMinimum(): 恢复默认设置,自己设置的最小值将不再生效,仍有提供的数据进行自动计算得到
- setInverted(boolean enabled): 倒置高低值,大值将会在底部出现,小值将会在顶部出现
- setSpaceTop(float percent): 设置距顶部的间距(占总轴的范围的百分比)
- setSpaceBottom(float percent): 设置距底部的间距(占总轴的范围的百分比)
- setShowOnlyMinMax(boolean enabled): 如果设置为true,将会只显示最小值和最大值,中间的数据将会忽略掉不显示(如果不是强制显示的话)
- setLabelCount(int count, boolean force): 设置y轴标签数,这个数字不是固定的除非force设置为true,如果force设置为true会精确绘制坐标值标签数,导致轴上数字不均匀
- setPosition(YAxisLabelPosition pos): 设置纵轴坐标值的绘制位置(图表内侧或者图表外侧 --- INSIDE_CHART or OUTSIDE_CHART)
- setGranularity(float gran): 设置y轴的最小间距,用于避免缩放到最小时,坐标轴上数据相互重叠
- setGranularityEnabled(boolean enabled): 可以在缩放时限制y轴间距,默认false
定制坐标轴样式
- setTextColor(int color): 设置坐标轴值标签的颜色
- setTextSize(float size): 设置坐标轴值标签的字体的大小
- setTypeface(Typeface tf): 给坐标轴值标签设置一个字体
- setGridColor(int color): 设置背景表格线的颜色
- setGridLineWidth(float width): 设置背景表格线的宽度
- setAxisLineColor(int color): 设置坐标轴线的颜色
- setAxisLineWidth(float width): 设置坐标轴线的宽度
- enableGridDashedLine(float lineLength, float spaceLength, float phase): 让背景表格线变成虚线模式就像 - - - - - 的样子,lineLength控制实线长度,spaceLength控制虚线长度,phase控制起始点
对坐标轴值进行格式化
可以使用IAxisValueFormatter接口来格式化坐标轴数据,使用axis.setValueFormatter(IAxisValueFormatter formatter)设置自己的定制数据格式
限制线
像边界线和约束线这种用于表示特殊信息的线我们称之为限制线,限制线在Y轴上横向呈现,在X轴上纵向呈现
- addLimitLine(LimitLine l): 向坐标轴上添加一条新的限制线
- removeLimitLine(LimitLine l): 从坐标轴上移除一条限制线
- setDrawLimitLinesBehindData(boolean enabled): 允许设置限制线和数据标签的图层顺序,为true的话限制线将绘制在数据的后面,否则绘制在前面,默认为false
限制线顾名思义是给用户提供格外信息的一种简洁、简单的线
例如,您的图表可能会显示用户的各种血压测量结果.为了通知用户,收缩压超过140毫米汞柱被认为是健康风险,你可以在140添加一个限制线来提供这些信息
YAxis leftAxis = chart.getAxisLeft();
LimitLine ll = new LimitLine(140f, "健康的血压线");
ll.setLineColor(Color.RED);
ll.setLineWidth(4f);
ll.setTextColor(Color.BLACK);
ll.setTextSize(12f);
// .. 更多的样式设置
leftAxis.addLimitLine(ll);
X轴
任何与横轴有关的数据信息都存放在X轴中,像折线图、柱状图、网状图、蜡烛图、雷达图等都有XAxis对象
获取X轴实例对象使用
XAxis xAxis = chart.getXAxis();
定制坐标轴数据
- setLabelRotationAngle(float angle): 设置X轴标签数据绘制的角度
- setPosition(XAxisPosition pos): 设置标签数据绘制的位置,可以选择以下的项:TOP,BOTTOM,BOTH_SIDED,TOP_INSIDE or BOTTOM_INSIDE.
示例代码
XAxis xAxis = chart.getXAxis();
xAxis.setPosition(XAxisPosition.BOTTOM);
xAxis.setTextSize(10f);
xAxis.setTextColor(Color.RED);
xAxis.setDrawAxisLine(true);
xAxis.setDrawGridLines(false);
// 设置定制的数据格式
xAxis.setValueFormatter(new MyCustomFormatter());
Y轴
任何与纵轴有关的数据信息都存放在Y轴中,像折线图、柱状图、网状图、蜡烛图等都有左右两个YAxis对象,雷达图只有一个YAxis对象
获取YAxis实例对象
YAxis leftAxis = chart.getAxisLeft();
YAxis rightAxis = chart.getAxisRight();
YAxis leftAxis = chart.getAxis(AxisDependency.LEFT);
YAxis yAxis = radarChart.getYAxis(); // 雷达图获取YAxis方法
在运行时,可以使用public AxisDependency getAxisDependency()来确定YAxis是图表的哪一边的
想要设置效果必须在给图表设置数据之前
Axis Dependency
默认情况下,所有添加到图表的数据都和左边的Y轴数据相对应,没有进一步设置的情况下右边的Y轴数据以及样式比例均与左边统一,如果你想要设置不同比例的Y轴,你可以通过设置对应的数据来绘制对应的坐标轴实现
LineDataSet dataSet = ...; // 获取dataset
dataSet.setAxisDependency(AxisDependency.RIGHT);
零线
除了网格线与YAxis上的每个值水平并排,还有所谓的零线,它在轴上的零(0)值处绘制,类似于网格线,但可以单独配置。
- setDrawZeroLine(boolean enabled): 是否绘制零线
- setZeroLineWidth(float width): 设置零线宽度
- setZeroLineColor(int color): 设置零线颜色
零线代码示例:
// 数据设置在左边坐标轴
YAxis left = mChart.getAxisLeft();
left.setDrawLabels(false); // 不设置坐标轴数据标签
left.setDrawAxisLine(false); // 不绘制坐标轴线
left.setDrawGridLines(false); // 不绘制网格线
left.setDrawZeroLine(true); // 绘制零线
mChart.getAxisRight().setEnabled(false); // 不设置右边Y轴
没有其他的线(坐标轴线、网格线等等)只有一条零线的效果
更多的代码示例:
YAxis yAxis = mChart.getAxisLeft();
yAxis.setTypeface(...); // 设置一个不同的字体
yAxis.setTextSize(12f); // 设置字体大小
yAxis.setAxisMinimum(0f); // 设置坐标轴从0开始
yAxis.setAxisMaximum(100f); // 设置坐标轴最大值为100
yAxis.setTextColor(Color.BLACK); // 设置字体颜色为黑色
yAxis.setValueFormatter(new MyValueFormatter());
yAxis.setGranularity(1f); // 设置间隔为1
yAxis.setLabelCount(6, true); // 设置标签个数
//... 更多
设置数据
折线图
如果想要给图表添加数据需要使用以下方式:
public void setData(ChartData data) { ... }
基类CharData包含在渲染时图表所需要的所有的数据和信息
对于每一种数据图表,都有一个CharData的子类用于给图表设置数据
在构造函数中,可以使用List extends IDataSet>作为数据去显示,
两种不同的构造函数
/** List constructor */
public LineData(List sets) { ... }
/** Constructor with one or multiple ILineDataSet objects */
public LineData(ILineDataSet...) { ... }
一个DataSet对象代表一组图表中一起的数据,这样可以在逻辑上分离图表上的不同组数据.
对于每种类型的图表,存在允许特定样式的扩展DataSet的不同对象(例如Line DataSet)
举个例子,如果你想要显示两家不同公司上一年季度性的财政收入,推荐使用两个LineDataSet,每一个中包含四组数据
那么如何去设置LineDataSet对象呢
public LineDataSet(List entries,String label){...}
可以看到,LineDataSet的构造函数中需要List
此label还可以进一步在LineData中去找到对应的LineDataSet对象
这些Entry的列表中包含了图表的所有数据,而Entry类就相当于X、Y坐标值的一个包装类,用于存放一个具体的坐标值
public Entry(float x, float y) { ... }
上面的例子,我们第一步可以创建一个用于存放公司收入的Entry的集合
List valsComp1 = new ArrayList();
List valsComp2 = new ArrayList();
然后填充数据,确保Entry内的X轴数据是精确的
Entry c1e1 = new Entry(0f, 100000f); // 一公司第一季度数据
valsComp1.add(c1e1);
Entry c1e2 = new Entry(1f, 140000f); // 一公司第二季度数据
valsComp1.add(c1e2);
// 继续添加
Entry c2e1 = new Entry(0f, 130000f); // 二公司第一季度数据
valsComp2.add(c2e1);
Entry c2e2 = new Entry(1f, 115000f); // 二公司第二季度数据
valsComp2.add(c2e2);
//...
现在我们可以通过这一系列数据去创建LineDataSet对象
LineDataSet setComp1 = new LineDataSet(valsComp1, "Company 1");
setComp1.setAxisDependency(AxisDependency.LEFT);
LineDataSet setComp2 = new LineDataSet(valsComp2, "Company 2");
setComp2.setAxisDependency(AxisDependency.LEFT);
通过使用setAxisDependency来指定具体数据绘制的轴,然后通过创建IDataSets的List来构成ChartData对象
// 使用ILineDataSet接口
List dataSets = new ArrayList();
dataSets.add(setComp1);
dataSets.add(setComp2);
LineData data = new LineData(dataSets);
mLineChart.setData(data);
mLineChart.invalidate(); // 刷新
在调用invalidate方法刷新后,数据就会被绘制出来
如果我们想特别定制X轴数据来替换原先的0到3,我们可以使用IAxisValueFormatter接口
这个接口可以让我们自定义X轴数据显示样式
举个例子,像以下这样设置数据格式:
// 绘制在X轴上的数据数组
final String[] quarters = new String[] { "Q1", "Q2", "Q3", "Q4" };
IAxisValueFormatter formatter = new IAxisValueFormatter() {
@Override
public String getFormattedValue(float value, AxisBase axis) {
return quarters[(int) value];
}
@Override
public int getDecimalDigits() { return 0; }
};
XAxis xAxis = mLineChart.getXAxis();
xAxis.setGranularity(1f); // 最小的间隔设置为1
xAxis.setValueFormatter(formatter);
最后渲染的图表的样子
BarChart,ScatterChart,BubbleChart和CandleStickChart的设置数据与LineChart一样
其中特殊的是BarChart将会在下面进行解释:
数据排序
如果List
我们可以使用EntryXComparator来进行排序
List entries = ...;
Collections.sort(entries, new EntryXComparator());
柱状图
柱状图的设置数据方式与折线图类似,最大的不同在于柱状图存放数据的BarEntry有一些不同的样式设置
创建BarDataSet
List entries = new ArrayList<>();
entries.add(new BarEntry(0f, 30f));
entries.add(new BarEntry(1f, 80f));
entries.add(new BarEntry(2f, 60f));
entries.add(new BarEntry(3f, 50f));
// 跳过第五个
entries.add(new BarEntry(5f, 70f));
entries.add(new BarEntry(6f, 60f));
BarDataSet set = new BarDataSet(entries, "BarDataSet");
将数据设置到图表上
BarData data = new BarData(set);
data.setBarWidth(0.9f); // 设置数据条的宽度
chart.setData(data);
chart.setFitBars(true); // 让X轴与所有的数据条适配
chart.invalidate(); // 刷新
当柱状图被创建时,每一个条都有1f的宽度,设置为0.9f的宽度后,将会在两个条各存在0.1f的间隔
设置setFitBars(true)将会让X轴的范围很好的适配柱状图,而不会出现有哪个条被边缘线切断
刷新后显示:
群组柱状图
YourData[] group1 = ...;
YourData[] group2 = ...;
List entriesGroup1 = new ArrayList<>();
List entriesGroup2 = new ArrayList<>();
// 填充数据
for(int i = 0; i < group1.length; i++) {
entriesGroup1.add(new BarEntry(i, group1.getValue()));
entriesGroup2.add(new BarEntry(i, group2.getValue()));
}
//两组数据
BarDataSet set1 = new BarDataSet(entriesGroup1, "Group 1");
BarDataSet set2 = new BarDataSet(entriesGroup2, "Group 2");
这样就获取到两组数据,现在用这两组数据去完成群组柱状图
float groupSpace = 0.06f; //群组间的间隔
float barSpace = 0.02f; // 每一个柱状条间隔
float barWidth = 0.45f; // 每一个柱状条的宽度
// (0.02 + 0.45) * 2 + 0.06 = 1.00 -> 总共合起来还是1f
BarData data = new BarData(set1, set2); //设置组数据
data.setBarWidth(barWidth); // 设置柱状条宽度
barChart.setData(data);
barChart.groupBars(1980f, groupSpace, barSpace); // 设置组样式宽度等
barChart.invalidate(); // 刷新
groupBars(...)对群组数据进行了具体的设置,这个方法的具体参数
public void groupBars(float fromX, float groupSpace, float barSpace) { ... }
fromX标识X轴数据从哪边开始进行渲染
最后渲染出来为:
通过使用setCenterAxisLabels(...)方法可以让标签数据正确显示在群组柱状条中间
XAxis xAxis = chart.getXAxis();
xAxis.setCenterAxisLabels(true);
叠加柱状图
设置与普通的柱状图类似,不同的是BarEntry的构造函数使用
public BarEntry(float x, float [] yValues) { ... }
第二个参数是一个叠加的数据值数组
BarEntry stackedEntry = new BarEntry(0f, new float[] { 10, 20, 30 });
这样在图表上显示高度为10,20,30的三段数据
饼图
不同于其他的图形,饼图的构造函数是这样的:
public PieEntry(float value, String label) { ... }
第一个参数即是当前所占区域的大小数据,第二个参数用于描述当前区域的信息
完整的饼图的创建
List entries = new ArrayList<>();
entries.add(new PieEntry(18.5f, "Green"));
entries.add(new PieEntry(26.7f, "Yellow"));
entries.add(new PieEntry(24.0f, "Red"));
entries.add(new PieEntry(30.8f, "Blue"));
PieDataSet set = new PieDataSet(entries, "Election Results");
PieData data = new PieData(set);
pieChart.setData(data);
pieChart.invalidate(); // 刷新
饼图没有X轴,数据的显示顺序由添加顺序来定义
渲染完成后:
设置颜色
在这个小例子中我们有两组数据用于代表两个公司季度收入,我们想要设置不同的颜色去区分它们
我们想要:
- Company1使用四种不同的红色去标注四个不同的季度数据
- Company2使用四种不同的绿色去标注四个不同的季度数据
LineDataSet setComp1 = new LineDataSet(valsComp1, "Company 1");
setComp1.setColors(new int[] { R.color.red1, R.color.red2, R.color.red3, R.color.red4 }, Context);
LineDataSet setComp2 = new LineDataSet(valsComp2, "Company 2");
setComp2.setColors(new int[] { R.color.green1, R.color.green2, R.color.green3, R.color.green4 }, Context);
给DataSet设置颜色的方法
- setColors(int [] colors, Context c): 通过使用 new Int[]{R.color.red,...}的形式给dataset提供颜色数据
- setColors(int [] colors):通过使用 new Int[]{R.color.red,...}的形式给dataset提供颜色数据,必须确保在调用之前颜色都是可用的
- setColors(ArrayList
colors): 提供List类型的颜色集合,必须确保在调用之前颜色都是可用的 - setColor(int color): 设置单一的颜色,在内部还是创建数组并添加这个颜色
当然也可以使用颜色模板
LineDataSet set = new LineDataSet(...);
set.setColors(ColorTemplate.VORDIPLOM_COLORS);
在没有设置颜色的时候,将会使用默认的颜色
ValueFormatter接口
IValueFormatter接口用于创建自定义格式类来在图表绘制之前格式数据
使用IValueFormatter,简单的创建一个类去实现这个接口,并返回你从getFormattedValue(...)方法获取的数据想要显示的样子
创建一个格式化类
public class MyValueFormatter implements IValueFormatter {
private DecimalFormat mFormat;
public MyValueFormatter() {
mFormat = new DecimalFormat("###,###,##0.0"); // 使用金融类型的格式
}
@Override
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
// 写下你的代码逻辑
return mFormat.format(value) + " $"; // 比如在数据前添加一个$符
}
}
给ChartData或者DataSet添加格式化
// 图表内的数据均使用这种格式
lineData.setValueFormatter(new MyValueFormatter());
// 仅在该DataSet内使用这种格式
lineDataSet.setValueFormatter(new MyValueFormatter());
预置格式类
- LargeValueFormatter: 用于格式化大数据 超过"1,000"的值将会被格式化为"1K",超过"1,000,000"将会变成"1M",超过"1,000,000,000"将会变成"1M",并且像one trillion这样的数据将会被格式成"1t".
- PercentFormatter: 使用百分比修饰数据在饼图中很有用. 50 -> 50.0 %
- StackedValueFormatter: 用于层叠柱状图中,用于格式数据是否是显示多层数据还是仅仅只显示最顶部的数据
AxisValueFormatter接口
创建一个格式化类
创建一个类实现IAxisValueFormatter接口,用于格式化坐标轴上的值
public class MyYAxisValueFormatter implements IAxisValueFormatter {
private DecimalFormat mFormat;
public MyAxisValueFormatter() {
//格式化数字
mFormat = new DecimalFormat("###,###,##0.0");
}
@Override
public String getFormattedValue(float value, AxisBase axis) {
// value参数标识在坐标轴上的位置或者说是数据值,axis标识是哪个坐标轴
return mFormat.format(value) + " $";
}
/** 只有为数字时返回 其余返回0*/
@Override
public int getDecimalDigits() { return 1; }
}
下面的例子展示怎么把数组中的数据展示到坐标轴上去
public class MyXAxisValueFormatter implements IAxisValueFormatter {
private String[] mValues;
public MyXAxisValueFormatter(String[] values) {
this.mValues = values;
}
@Override
public String getFormattedValue(float value, AxisBase axis) {
return mValues[(int) value];
}
@Override
public int getDecimalDigits() { return 0; }
}
设置格式化类
在创建好格式化类之后,简单去运用它
YAxis left = chart.getAxisLeft();
left.setValueFormatter(new MyYAxisValueFormatter());
String[] values = new String[] { ... };
XAxis xAxis = chart.getXAxis();
xAxis.setValueFormatter(new MyXAxisValueFormatter(values));
设置完之后,图表用格式化类来具体指定值来代替默认的坐标轴的最小值和最大值范围
限制间隔
如果使用上面的数组格式化坐标轴标签值,可以使用一下的代码去限制标签间的间隔
axis.setGranularity(1f);
这将可以预防坐标轴绘制重叠的数据,因为在缩放到一定的程度时,图表将会停止计算更小的标签范围
预置格式化类
- LargeValueFormatter: 用于格式化大数据 超过"1,000"的值将会被格式化为"1K",超过"1,000,000"将会变成"1M",超过"1,000,000,000"将会变成"1M",并且像one trillion这样的数据将会被格式成"1t".
- PercentFormatter: 使用百分比修饰数据在饼图中很有用. 50 -> 50.0 %
通用的图表和样式设置
刷新
- invalidate(): 使用这个方法刷新图表将会重新绘制,更改图表后想要生效必须调用
- notifyDataSetChanged(): 让图表知道依赖的数据发生变化时调用,调用后图表会重新计算,在使用动态数据时很有用
日志
- setLogEnabled(boolean enabled): 设置为true时将会打印日志信息,但是打开将会影响性能所以不是必要的话请关闭
大体的样式设置
下面是一些可以直接在Chart上使用的样式设置方法
- setBackgroundColor(int color): 设置整个图表的背景颜色,也可以在.xml布局文件中进行设置
- setDescription(String desc): 在图表的右下角设置一个图表描述标注
- setDescriptionColor(int color): 设置图表描述的字体颜色
- setDescriptionPosition(float x, float y): 设置图表描述的显示位置
- setDescriptionTypeface(Typeface t): 设置图表描述的字体样式
- setDescriptionTextSize(float size): 设置图表描述的字体大小,通过像素值设置或者使用min(6f)、max(16f)
- setNoDataText(String text): 如果图表没有数据时显示的标注
- setDrawGridBackground(boolean enabled): 如果开启的话,图表绘制区域背后的矩形区域将会被绘制
- setGridBackgroundColor(int color): 设置背景矩形的颜色
- setDrawBorders(boolean enabled): 设置是否绘制图表边框
- setBorderColor(int color): 设置边框颜色
- setBorderWidth(float width): 设置边框线宽,单位为dp
- setMaxVisibleValueCount(int count): 设置图表可见数据标签的最大个数,只有当setDrawValues()开启时生效
具体的图表和样式设置
Line-, Bar-, Scatter-, Candle- & BubbleChart
- setAutoScaleMinMaxEnabled(boolean enabled): 根据最大最小数据值图表进行自动缩放,在展示金融类型的数据时很有趣,默认关闭
- setKeepPositionOnRotation(boolean enabled): 设置在转变方向时(横屏竖屏),图表的缩放滚动不发生改变,默认关闭
BarChart
- setDrawValueAboveBar(boolean enabled): 设置为true时,数据将会被渲染在数据条上方,而不是在顶部的下方显示
- setDrawBarShadow(boolean enabled): 设置为true时,将会在数据条背后根据最大值绘制阴影,但是开启将会降低大概40%的性能
- setDrawValuesForWholeStack(boolean enabled): 如果设置为true,堆叠条的所有值都会单独绘制,而不仅仅是绘制它们的总和。
- setDrawHighlightArrow(boolean enabled): 设置为true时将会在数据高亮时,在数据条上方高亮绘制箭头
PieChart
- setDrawSliceText(boolean enabled): 设置为true,将会在饼图片内绘制文字
- setUsePercentValues(boolean enabled): 当开启时,将不会使用原来的数据值,而是百分比格式过得到的百分比数据
- setCenterText(SpannableString text): 设置为true时文字将会在图表中间绘制,过长的文字将会被自动缩略以免绘制到饼图片上
- setCenterTextRadiusPercent(float percent): 设置中心文本边界框的矩形半径,作为饼图孔的百分比,默认值1.f(100%)
- setHoleRadius(float percent): 以最大半径的百分比(最大半径=整个图表的半径)来设置饼图中心的孔半径,默认为50%
- setTransparentCircleRadius(float percent): 设置饼图中孔旁边的透明圆的半径,以最大半径的百分比表示(最大半径=整个图表的半径),默认为55%->默认情况下比中心孔大5%
- setTransparentCircleColor(int color): 设置透明圆的颜色
- setTransparentCircleAlpha(int alpha): 设置透明圆的透明度
- setMaxAngle(float maxangle): 设置饼图的角度. 360f意味着是一个整圆的饼图,180f就是一个半圆的饼图.默认值360f
RadarChart
- setSkipWebLineCount(int count): 允许跳过绘制来自图表中心的网络线,在线特别多的情况下很有用
图例
图例通常有一个标识和一字符串组成,标识为代表该数据的DataSet的颜色决定,字符串是DataSet的描述
获取图例对象
Legend legend = chart.getLegend();
- setEnabled(boolean enabled): 设置图例是否被绘制
设置图例的样式
- setTextColor(int color): 设置图例上的字体颜色
- setTextSize(float size): 设置图例字体大小
- setTypeface(Typeface tf): 设置图例字体
大小
- setWordWrapEnabled(boolean enabled): 如果启用,图例的内容将不会剪切到图表边界外,而是创建一个新的线条即换行.请注意,这会降低性能,仅适用于图表下面的图例
- setMaxSizePercent(float maxSize): 设置图表相对于View的最大相对大小,默认为0.95即95%
自定义图例
- setPosition(LegendPosition pos): 设置图例要显示的位置. 可以设置这些值:RIGHT_OF_CHART,RIGHT_OF_CHART_CENTER,RIGHT_OF_CHART_INSIDE,BELOW_CHART_LEFT,BELOW_CHART_RIGHT,BELOW_CHART_CENTER or PIECHART_CENTER(只有饼图有)等等更多
- setForm(LegendForm shape): 设置图例显示的样式可以选择SQUARE(方形图例),CIRCLE(圆形图例) or LINE(线型图例).
- setFormSize(float size): 设置图例大小
- setXEntrySpace(float space): 设置如果在X轴上的图例的间距
- setYEntrySpace(float space): 设置如果在Y轴上的图例的间距
- setFormToTextSpace(float space): 设置图例上图示和文字之间的间距
设置自定义的标签
- setCustom(int[] colors, String[] labels): 自定义标签颜色和文字内容,两个数组的大小必须相等
- resetCustom():将会重置图例标签,根据默认的自动计算得到默认的图例标签
- setExtra(int[] colors, String[] labels): 给默认显示的图例增加新的内容,如果默认内容已经计算完毕,需要调用notifyDataSetChanged()来生效
例子
Legend l = chart.getLegend();
l.setFormSize(10f);
l.setForm(LegendForm.CIRCLE);
l.setPosition(LegendPosition.BELOW_CHART_LEFT);
l.setTypeface(...);
l.setTextSize(12f);
l.setTextColor(Color.BLACK);
l.setXEntrySpace(5f);
l.setYEntrySpace(5f);
l.setCustom(ColorTemplate.VORDIPLOM_COLORS, new String[] { "Set1", "Set2", "Set3", "Set4", "Set5" });
// and many more...
动态实时数据
MPAndroidChart并不支持实时数据,但是为了向图表添加新数据或动态删除数据,有各种方法可以将Entry对象添加到已有的DataSet对象或从已有的ChartData对象中删除DataSet对象
动态添加删除数据
Class DataSet(以及所有子类):
- addEntry(Entry e): 向DataSet中添加一个Entry对象
Class ChartData(以及所有子类):
- addEntry(Entry e, int dataSetIndex): 将Entry对象添加到内部的某一个DataSet(由dataSetIndex决定)中去
- addDataSet(DataSet d): 添加一个DataSet到ChartData中去
同样也有删除数据的方法
Class DataSet(以及所有子类):
- public boolean removeFirst(): 删除内部的第一个Entry对,删除成功返回true,失败返回false
- public boolean removeLast(): 删除内部的最后一个Entry对,删除成功返回true,失败返回false
- public boolean removeEntry(Entry e): 删除指定的一个Entry对(传入这个Entry对象),删除成功返回true,失败返回false
- public boolean removeEntry(int xIndex): 删除指定的一个Entry对(传入这个Entry对象的位置索引),删除成功返回true,失败返回false
Class ChartData(以及所有子类):
- public boolean removeEntry(Entry e, int dataSetIndex): 删除内部某一个DataSet(由dataSetIndex决定)的第一个Entry对,删除成功返回true,失败返回false
- public boolean removeEntry(int xIndex, int dataSetIndex): 删除内部某一个DataSet(由dataSetIndex决定)的一个Entry对(传入这个Entry对象的位置索引),删除成功返回true,失败返回false
- public boolean removeDataSet(DataSet d): 删除指定的一个dataSet(传入这个dataSet对象),删除成功返回true,失败返回false
- public boolean removeDataSet(int index): 删除指定的一个dataSet(传入这个dataSet对象位置索引),删除成功返回true,失败返回false
一定要记住
在动态删除或者添加数据之后,一定要在调用invalidate()刷新页面之前调用notifyDataSetChanged()方法更新数据
// EXAMPLE 1
// add entries to the "data" object
exampleData.addEntry(...);
chart.notifyDataSetChanged(); // 让Chart知道数据发生变化
chart.invalidate(); // 刷新
// EXAMPLE 2
// add entries to "dataSet" object
dataSet.addEntry(...);
exampleData.notifyDataChanged(); // 让DataSet知道数据发生变化
chart.notifyDataSetChanged(); // 让Chart知道数据发生变化
chart.invalidate(); // 刷新
调整视窗显示
这些方法只适用于LineChart,BarChart,ScatterChart和CandleStickChart
规定哪些可以显示
- setVisibleXRangeMaximum(float maxXRange): 设置视窗X轴显示的范围最大值,如果设置为10,那么超过10个数据的值在不滚动的情况下将不会显示
- setVisibleXRangeMinimum(float minXRange): 设置视窗X轴显示的范围最小值,如果设置为10,那么在缩放的时候始终将有10个数据显示在图表上
- setVisibleYRangeMaximum(float maxYRange, AxisDependency axis): 设置视窗Y轴显示的范围最大值,如果设置为10,那么超过10个数据的值在不滚动的情况下将不会显示,设置存在在哪一边的Y轴
- setViewPortOffsets(float left, float top, float right, float bottom): 为当前ViewPort设置自定义偏移量(实际图表窗口两侧的偏移量),设置这将阻止图表自动计算偏移量, 使用resetViewPortOffsets()来取消这个. 只有当你知道你在做什么时才使用这个方法
- resetViewPortOffsets(): 重置自定义偏移量,重新让图表自己进行计算
- setExtraOffsets(float left, float top, float right, float bottom): 在自动计算的偏移量基础上再加上额外的偏移量,但这个偏移量不会影响自动计算出来的
移动View
- fitScreen(): 重置所有的移动和缩放,并让图表完全适配它的边界(完全缩小).
- moveViewToX(float xValue): 将当前视窗的左侧(边缘)移动到指定的x值。.
- moveViewToY(float yValue, AxisDependency axis): 将根据左边或者右边Y轴选中的数据使视窗将该值处于视窗中间
- moveViewTo(float xValue, float yValue, AxisDependency axis): 上面两个方法的集合,就是将视窗焦点聚集到选中的某一点(视窗左边线在点上)
- centerViewTo(float xValue, float yValue, AxisDependency axis): 上面两个方法的集合,就是将视窗焦点聚集到选中的某一点(视窗中心线在点上)
使用动画移动View
- moveViewToAnimated(float xValue, float yValue, AxisDependency axis, long duration): 使用动画效果将左边缘移至所要到的点
- centerViewToAnimated(float xValue, float yValue, AxisDependency axis, long duration): 使用动画效果将中心移至所要到的点
所有的moveViewTo类似的方法都会自动调用invalidate方法去刷新页面,不需要手动去调用
缩放(以代码方式)
- zoomIn(): 以1.4f的缩放比系数放大视图中心焦点
- zoomOut(): 从视图中心焦点以0.7f的缩放比系数缩小视图
- zoom(float scaleX, float scaleY, float x, float y): 自定义缩放比,自定义缩放中心,记住 1f缩放值等于没有缩放 0到1之间为缩小操作,1以上为放大操作
- zoom(float scaleX, float scaleY, float xValue, float yValue, AxisDependency axis): 和上面的方法一样,增加了指定哪一边的Y轴
缩放动画
- zoomAndCenterAnimated(float scaleX, float scaleY, float xValue, float yValue, AxisDependency axis, long duration):使用动画进行具体缩放比的缩放操作
例子:
chart.setData(...);
// 开始设置视窗
chart.setVisibleXRangeMaximum(20);
chart.moveViewToX(10);
动画
所有的图表都提供了动画以供操作使用
有三种不同的动画存在
- animateX(int durationMillis): 横向变换时的动画,设置动画时长
- animateY(int durationMillis): 纵向变换时的动画,设置动画时长
- animateXY(int xDuration, int yDuration): 横向纵向动画合集,分别设置动画时长
mChart.animateX(3000); // animate horizontal 3000 milliseconds
mChart.animateY(3000); // animate vertical 3000 milliseconds
mChart.animateXY(3000, 3000); // animate horizontal and vertical 3000 milliseconds
平缓动画效果
你可以从Easing.EasingOption中选择想要的预置平缓动画效果
public enum EasingOption {
Linear,
EaseInQuad,
EaseOutQuad,
EaseInOutQuad,
EaseInCubic,
EaseOutCubic,
EaseInOutCubic,
EaseInQuart,
EaseOutQuart,
EaseInOutQuart,
EaseInSine,
EaseOutSine,
EaseInOutSine,
EaseInExpo,
EaseOutExpo,
EaseInOutExpo,
EaseInCirc,
EaseOutCirc,
EaseInOutCirc,
EaseInElastic,
EaseOutElastic,
EaseInOutElastic,
EaseInBack,
EaseOutBack,
EaseInOutBack,
EaseInBounce,
EaseOutBounce,
EaseInOutBounce,
}
有两种设置平缓动画效果的方法
- 直接使用预设(所有Android版本均可使用)
public void animateY(int durationmillis, Easing.EasingOption option);
例如调用时就将动画效果设置进去
mChart.animateY(3000, Easing.EasingOption.EaseOutBack);
- 自定义平滑效果(仅支持Android3.0以上版本)
public void animateY(int durationmillis, EasingFunction function);
创建一个类去实现EasingFunction接口,在该类中实现自己的逻辑
/**
* Interface for creating custom made easing functions.
*/
public interface EasingFunction {
/**
* Called everytime the animation is updated.
* @param input - the time passed since the animation started (value between 0 and 1)
*/
public float getInterpolation(float input);
}
调用的时候(在Android3.0以下的版本中将会Crash掉)
mChart.animateY(3000, new MyEasingFunction());
IMarker接口(图表数据标注接口)
IMarker接口是你能够在创建自定义的标注样式去显示你图表中高亮的数据
IMarker定义的像这样:
public interface IMarker {
/**
* @return The desired (general) offset you wish the IMarker to have on the x- and y-axis.
* By returning x: -(width / 2) you will center the IMarker horizontally.
* By returning y: -(height / 2) you will center the IMarker vertically.
*/
MPPointF getOffset();
/**
* @return The offset for drawing at the specific `point`. This allows conditional adjusting of the Marker position.
* If you have no adjustments to make, return getOffset().
*
* @param posX This is the X position at which the marker wants to be drawn.
* You can adjust the offset conditionally based on this argument.
* @param posY This is the X position at which the marker wants to be drawn.
* You can adjust the offset conditionally based on this argument.
*/
MPPointF getOffsetForDrawingAtPos(float posX, float posY);
/**
* 刷新方法
*
* @param e The Entry the IMarker belongs to. This can also be any subclass of Entry, like BarEntry or
* CandleEntry, simply cast it at runtime.
* @param highlight The highlight object contains information about the highlighted value such as it's dataset-index, the
* selected range or stack-index (only stacked bar entries).
*/
void refreshContent(Entry e, Highlight highlight);
/**
* 使用传递来的Canvas对象在指定位置绘制对应的标注
*
* @param canvas
* @param posX
* @param posY
*/
void draw(Canvas canvas, float posX, float posY);
}
创建一个标注View
你需要创建一个类去实现IMarker接口
public class YourMarkerView implements IMarker { ... }
根据你自己的需要去实现你所要实现的方法
下面例子的这种方法更简单,不需要实现IMarker接口提供的所有方法
只有特定的方法可以被覆盖和定制,最重要的是重写refreshContent方法来调整由标记绘制的数据
public class YourMarkerView extends MarkerView {
private TextView tvContent;
public MyMarkerView(Context context, int layoutResource) {
super(context, layoutResource);
// find your layout components
tvContent = (TextView) findViewById(R.id.tvContent);
}
// callbacks everytime the MarkerView is redrawn, can be used to update the
// content (user-interface)
@Override
public void refreshContent(Entry e, Highlight highlight) {
tvContent.setText("" + e.getY());
// this will perform necessary layouting
super.refreshContent(e, highlight);
}
private MPPointF mOffset;
@Override
public MPPointF getOffset() {
if(mOffset == null) {
// center the marker horizontally and vertically
mOffset = new MPPointF(-(getWidth() / 2), -getHeight());
}
return mOffset;
}
}
获取和设置标注对象
想要在图表中使用你设置好的marker,使用setMarker方法
IMarker marker = new YourMarkerView();
chart.setMarker(marker);
获取一个已经存在的marker,使用getMarker()方法
IMarker marker = chart.getMarker();
预置的标注
- MarkerView: 允许加载一个layout去展示对应的标注,继承这个类并重写refreshContent(...)方法来使用标注数据
- MarkerImage: 允许加载一张图片在标注上显示对应的图片,继承这个类并重写refreshContent(...)方法来使用标注数据
ChartData类 图表数据类
ChartData类是所有图表数据类的基类
public class LineData extends ChartData { ...
下面的是已经被实现且在子类中可以使用的方法
数据样式
- setValueTextColor(int color): 设置数据颜色
- setValueTextColors(List colors): 设置数据颜色(传入颜色数组)
- setValueTextSize(float size): 设置数据字体大小
- setValueTypeface(Typeface tf): 设置数据字体
- setValueFormatter(ValueFormatter f): 设置数据格式化类
- setDrawValues(boolean enabled): 控制是否绘制数据值
获取数据
- getDataSetByIndex(int index): 根据索引值获取DataSet
- contains(Entry entry): 查看是否包含某个具体的Entry对,对性能损耗严重
- contains(T dataSet): 查看是否包含某个DataSet
清空数据
- clearValues(): 清除所DataSet数据和依赖的Entry对数据,但不会删除X轴上的坐标轴数据
高亮
- setHighlightEnabled(boolean enabled): 设置是否允许高亮.
- setDrawVerticalHighlightIndicator(boolean enabled): 是否绘制纵向高亮指示线
- setDrawHorizontalHighlightIndicator(boolean enabled): 是否绘制横向高亮指示线
动态数据
- notifyDataChanged(): 让数据类知道数据发生了变化
ChartData的子类
BarData
- setGroupSpace(float percent): 设置一组数据间的间距.100是一个数据条的长度,默认80
- isGrouped(): 判断该柱状图是不是群组柱状图
ScatterData
- getGreatestShapeSize(): 通过内部的数据查询最大的Shape值.
PieData
- getDataSet(): 获取DataSet,PieData不能拥有多个DataSet
- setDataSet(PieDataSet set): 设置DataSet
BubbleData
- setHighlightCircleWidth(float width): 设置高亮圈宽度
DataSet数据类
DataSet数据类用法与ChartData几乎一模一样
子类
Line-, Bar-, Scatter-, Bubble- & CandleDataSet
- setHighLightColor(int color): 设置高亮颜色
Line-, Bar-, Scatter-, Candle- & RadarDataSet
- setDrawHighlightIndicators(boolean enabled): 控制是否绘制高亮指示线
- setHighlightLineWidth(float width): 设置高亮指示线宽度
Line- & RadarDataSet
- setFillColor(int color): 设置填充颜色
- setFillAlpha(int alpha): 设置填充透明度
- setFillDrawable(Drawable d): 选择一个Drawable去填充
- setDrawFilled(boolean filled): 开启之后将会完全填充绘制,而不是仅仅只有一条线,关闭这项将有性能上的提升,小于Android4.3无法使用,默认关闭
- setLineWidth(float width): 设置数据线宽度
LineDataSet
- setCircleRadius(float size): 设置圆形指示器的圆弧度,默认值4f
- setDrawCircles(boolean enabled):设置是否绘制圆形指示器,默认true
- setDrawCubic(boolean enabled): 开启之后数据线将显示成立体模式,对性能有影响 默认关闭
- setCubicIntensity(float intensity): 设置立体强度 最大值为1f, 最小0.05f,默认0.2f
- setCircleColor(int color): 设置圆形指示器的颜色
- setCircleColors(List colors): 设置圆形指示器颜色
- setCircleColorHole(int color): 设置圆形指示器内部圆的颜色
- setDrawCircleHole(boolean enabled): 设置是否绘制圆形指示器内部圆
- enableDashedLine(float lineLength, float spaceLength, float phase): 设置使用虚线数据线
BarDataSet
- setBarSpacePercent(float percent): 设置条形图间距百分比
- setBarShadowColor(int color): 设置条形图背景阴影颜色
- setHighLightAlpha(int alpha): 设置条形图背景高亮指示器的透明度,最小0(完全透明),最大255(完全显示).
- setStackLabels(String[] labels): 给层叠条形图设置多个标签值
ScatterDataSet
- setScatterShapeSize(float size): 设置形状大小
- setScatterShape(ScatterShape shape): 设置形状样式
CandleDataSet
- setBodySpace(float space): 设置左右两个蜡烛图的间距,默认0.1f(10%),最大0.45f,最小0f
- setShadowWidth(float width): 设置蜡烛阴影线的宽度,默认3f.
- setShadowColor(int color): 设置阴影颜色.
- setDecreasingColor(int color): 当开盘比收盘数据大时,使用该颜色显示.
- setIncreasingColor(int color): 当开盘比收盘数据小时,使用该颜色显示.
- setDecreasingPaintStyle(Paint.Style style): 当开盘比收盘数据大时,使用该样式绘制(填充或者描边).
- setIncreasingPaintStyle(Paint.Style style): 当开盘比收盘数据小时,使用该样式绘制(填充或者描边).
BubbleDataSet
- setHighlightCircleWidth(float width): 设置高亮圈的宽度
PieDataSet
- setSliceSpace(float degrees): 设置分开的饼图两片间的间距,默认:0没有间距,最大20,最小0
- setSelectionShift(float shift): 设置选中的饼图片浮动离开中心点的距离,默认12f
ViewPortHandler 视窗控制
初始化
通过以下方式来获取视窗Handler实例
ViewPortHandler handler = chart.getViewPortHandler();
缩放和位移
- getScaleX(): 获取X轴缩放等级.
- getScaleY(): 获取Y轴缩放等级.
- getTransX(): 获取X轴上的位移量.
- getTransY(): 获取Y轴上的位移量.
图表尺寸和内容
- getChartWidth(): 获取图表宽度
- getChartHeight(): 获取图表高度
- getContentRect(): 返回图表内容所在的矩形RectF对象.
FillFormatter接口 数据格式化
新建一个类实现FillFormatter接口
并重写下面这个方法
public float getFillLinePosition(LineDataSet dataSet, LineDataProvider provider)
可以实现单个的DataSet的实现在哪个位置停止绘制
public class MyCustomFillFormatter implements FillFormatter {
@Override
public float getFillLinePosition(LineDataSet dataSet, LineDataProvider dataProvider) {
float myDesiredFillPosition = ...;
// put your logic here...
return myDesiredFillPosition;
}
}
把格式化添加到图表中
lineDataSet.setFillFormatter(new MyCustomFillFormatter());
默认的实现---->DefaultFillFormatter.