最近需要在Android上将数据展示为图表,偶然间在GitHub上找到一个很不错的Android图表框架,支持柱状图,饼图,曲线图,点的误差图等等等,关键一点,好看!。
闲话少说,先上图(CSDN出问题了。。。图片传不上):
本篇博客,我们介绍其中两种:柱状图和饼状图,其他的示例可以查看该大神的GitHub:https://github.com/PhilJay/MPAndroidChart
或者下载我整理的项目:http://download.csdn.net/detail/zengxyuyu/9848370
(app是对MPAndroidChart的整理,mychart是自己修改的(柱状图和饼图),realmTest是一个realm的demo,其它两个是放大镜的demo)
首先我们看看饼图:
饼图支持在中间填写文本,并可根据需求更改大小、颜色,点击饼图中的某一块会放大该块。
public class PieChartActivity extends Activity implements OnChartValueSelectedListener {
@BindView(R.id.chart1)
PieChart chart1;
private String[] labels = {"香蕉", "葡萄", "菠萝", "桃子", "樱桃"};
private float[] values = {25f, 33f, 10f, 17f, 15f};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_piechart);
ButterKnife.bind(this);
initChartSetting();
}
private void initChartSetting() {
chart1.setUsePercentValues(true);
chart1.getDescription().setEnabled(false);
chart1.setExtraOffsets(5, 10, 5, 5);
//设置减速摩擦系数
chart1.setDragDecelerationFrictionCoef(0.95f);
chart1.setCenterTextTypeface(Typeface.DEFAULT);
chart1.setCenterText(generateCenterText());
chart1.setDrawHoleEnabled(true);
chart1.setHoleColor(Color.WHITE);
chart1.setTransparentCircleColor(Color.WHITE);
chart1.setTransparentCircleAlpha(110);
chart1.setHoleRadius(58f);
chart1.setTransparentCircleRadius(61f);
chart1.setDrawCenterText(true);
chart1.setRotationAngle(0);
// enable rotation of the chart by touch
chart1.setRotationEnabled(true);
//应该是允许点击某一块时放大
chart1.setHighlightPerTapEnabled(true);
// chart1.setDrawUnitsInChart(true);
chart1.setOnChartValueSelectedListener(this);
chart1.animateY(1400, Easing.EasingOption.EaseInOutQuad);
// chart1.spin(2000, 0, 360);
setData(labels,values);
Legend l = chart1.getLegend();
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
l.setOrientation(Legend.LegendOrientation.VERTICAL);
l.setDrawInside(false);
l.setXEntrySpace(7f);
l.setYEntrySpace(0f);
l.setYOffset(0f);
// entry label styling
chart1.setEntryLabelColor(Color.WHITE);
chart1.setEntryLabelTypeface(Typeface.DEFAULT);
chart1.setEntryLabelTextSize(12f);
}
private SpannableString generateCenterText() {
SpannableString s = new SpannableString("饼状图\n测试用例");
s.setSpan(new RelativeSizeSpan(1.7f), 0, 4, 0);
s.setSpan(new StyleSpan(Typeface.NORMAL), 4, s.length(), 0);
s.setSpan(new ForegroundColorSpan(ColorTemplate.getHoloBlue()), 4, s.length(), 0);
return s;
}
private void setData(String[] labels, float[] values) {
ArrayList<PieEntry> entries = new ArrayList<PieEntry>();
if (labels.length != values.length)
return;
for (int i = 0; i < labels.length; i++) {
entries.add(new PieEntry(values[i], labels[i], getResources().getDrawable(R.drawable.star)));
}
PieDataSet dataSet = new PieDataSet(entries, "个人爱好");
dataSet.setDrawIcons(false);
dataSet.setSliceSpace(3f);
dataSet.setIconsOffset(new MPPointF(0, 40));
dataSet.setSelectionShift(5f);
// 添加颜色
ArrayList<Integer> colors = new ArrayList<Integer>();
for (int c : ColorTemplate.VORDIPLOM_COLORS)
colors.add(c);
for (int c : ColorTemplate.JOYFUL_COLORS)
colors.add(c);
for (int c : ColorTemplate.COLORFUL_COLORS)
colors.add(c);
for (int c : ColorTemplate.LIBERTY_COLORS)
colors.add(c);
for (int c : ColorTemplate.PASTEL_COLORS)
colors.add(c);
colors.add(ColorTemplate.getHoloBlue());
dataSet.setColors(colors);
//dataSet.setSelectionShift(0f);
PieData data = new PieData(dataSet);
data.setValueFormatter(new PercentFormatter());
data.setValueTextSize(15f);
//设置值的颜色
data.setValueTextColor(Color.WHITE);
data.setValueTypeface(Typeface.DEFAULT);
chart1.setData(data);
// undo all highlights
chart1.highlightValues(null);
//开始绘制
chart1.invalidate();
}
@Override
public void onValueSelected(Entry e, Highlight h) {
if (e == null)
return;
Log.e("选中:", "Value: " + e.getY() + ", index: " + h.getX()
+ ", DataSet index: " + h.getDataSetIndex());
}
@Override
public void onNothingSelected() {
Log.e("PieChartActivity", "没有选中任何一个");
}
}
然后,我们再看看柱状图,柱状图比较复杂,需要重写格式化类,对X轴和Y轴的数据进行格式化操作,当然,你也可以直接返回,比如我这里写的对X轴数据的格式化类:
public class XAxisValueFormatter implements IAxisValueFormatter {
private String[] xValues;
public XAxisValueFormatter(String[] xValues) {
this.xValues = xValues;
}
@Override
public String getFormattedValue(float value, AxisBase axis) {
return xValues[(int) value];
}
}
如果你的y轴数据是代表数据(比如,个数,大小等),那么,你可以直接复制这段代码:
public class YAxisValueFormatter implements IAxisValueFormatter
{
private DecimalFormat mFormat;
public YAxisValueFormatter() {
mFormat = new DecimalFormat("###,###,###,##0.0");
}
@Override
public String getFormattedValue(float value, AxisBase axis) {
return mFormat.format(value);
}
}
然后,我们说一下点击柱子会出现的东西,提示(有点像QQ消息):
public class XYMarkerView extends MarkerView {
private TextView tvContent;
private IAxisValueFormatter xAxisValueFormatter;
private DecimalFormat format;
public XYMarkerView(Context context, IAxisValueFormatter xAxisValueFormatter) {
super(context, R.layout.custom_marker_view);
this.xAxisValueFormatter = xAxisValueFormatter;
tvContent = (TextView) findViewById(R.id.tvContent);
format = new DecimalFormat("###.0");
}
@Override
public void refreshContent(Entry e, Highlight highlight) {
tvContent.setText("x: " + xAxisValueFormatter.getFormattedValue(e.getX(), null) + ", y: " + format.format(e.getY()));
super.refreshContent(e, highlight);
}
@Override
public MPPointF getOffset() {
return new MPPointF(-(getWidth() / 2), -getHeight());
}
}
最后,重头戏,柱状图的代码:
public class BartChartActivity extends Activity implements OnChartValueSelectedListener {
@BindView(R.id.chart1)
BarChart chart1;
private String[] xValues = {"香蕉", "葡萄", "菠萝", "桃子", "樱桃"};
private float[] yValues = {25f, 33f, 10f, 17f, 15f};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_barchart);
ButterKnife.bind(this);
initSetting();
}
private void initSetting() {
chart1.setOnChartValueSelectedListener(this);
chart1.setDrawBarShadow(false);
chart1.setDrawValueAboveBar(true);
chart1.getDescription().setEnabled(false);
//设置当超过多少个x值时不在柱状图的柱子上绘制y值,这里设置为60
chart1.setMaxVisibleValueCount(60);
// 只能在x或y轴上单独的缩放
chart1.setPinchZoom(false);
chart1.setDrawGridBackground(false);
// chart1.setDrawYLabels(false);
IAxisValueFormatter xAxisFormatter = new XAxisValueFormatter(xValues);
XAxis xAxis = chart1.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setTypeface(Typeface.DEFAULT);
xAxis.setDrawGridLines(false);
xAxis.setGranularity(1f);
xAxis.setTextSize(15);
xAxis.setLabelCount(xValues.length);
xAxis.setValueFormatter(xAxisFormatter);
IAxisValueFormatter custom = new YAxisValueFormatter();
YAxis leftAxis = chart1.getAxisLeft();
leftAxis.setTypeface(Typeface.DEFAULT);
leftAxis.setLabelCount(yValues.length, false);
leftAxis.setValueFormatter(custom);
leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
leftAxis.setTextSize(13);
leftAxis.setSpaceTop(15f);
leftAxis.setAxisMinimum(0f);
YAxis rightAxis = chart1.getAxisRight();
rightAxis.setDrawGridLines(false);
rightAxis.setTypeface(Typeface.DEFAULT);
rightAxis.setLabelCount(yValues.length, false);
rightAxis.setValueFormatter(custom);
rightAxis.setSpaceTop(15f);
rightAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true)
Legend l = chart1.getLegend();
l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
l.setDrawInside(false);
l.setForm(Legend.LegendForm.SQUARE);
l.setFormSize(9f);
l.setTextSize(11f);
l.setXEntrySpace(4f);
XYMarkerView mv = new XYMarkerView(this, xAxisFormatter);
mv.setChartView(chart1); // For bounds control
chart1.setMarker(mv); // Set the marker to the chart
setData(yValues);
}
private void setData(float[] yValues) {
ArrayList<BarEntry> y_list = new ArrayList<>();
for (int i = 0; i < yValues.length; i++) {
y_list.add(new BarEntry(i, yValues[i]));
}
BarDataSet set1;
if (chart1.getData() != null && chart1.getData().getDataSetCount() > 0) {
set1 = (BarDataSet) chart1.getData().getDataSetByIndex(0);
set1.setValues(y_list);
chart1.getData().notifyDataChanged();
chart1.notifyDataSetChanged();
} else {
set1 = new BarDataSet(y_list, "各种水果爱好人数");
set1.setDrawIcons(false);
set1.setColors(ColorTemplate.MATERIAL_COLORS);
ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
dataSets.add(set1);
BarData data = new BarData(dataSets);
data.setValueTextSize(10f);
data.setValueTypeface(Typeface.DEFAULT);
data.setBarWidth(0.9f);
chart1.setData(data);
}
}
@Override
public void onValueSelected(Entry e, Highlight h) {
}
@Override
public void onNothingSelected() {
}
}