300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > Android之MPAndroidChart库使用说明(柱状图 折线图 饼图和组合图.)

Android之MPAndroidChart库使用说明(柱状图 折线图 饼图和组合图.)

时间:2018-08-18 08:29:19

相关推荐

Android之MPAndroidChart库使用说明(柱状图 折线图 饼图和组合图.)

介绍:MPAndroidChart是一款基于Android的开源图表库,MPAndroidChart不仅可以在Android设备上绘制各种统计图表,而且可以对图表进行拖动和缩放操作,应用起来非常灵活。 MPAndroidChart同样拥有常用的图表类型:线型图、饼图、柱状图和散点图和雷达图。 github地址:/PhilJay/MPAndroidChart

适用场景: 如果您的应用涉及大量数据,利用图表,用表显示的数据可能会得到一个好得多的用户体验。

一、把MPAndroidChart导入我们的项目: Gradle依赖: 在Project级别的build.gradle中添加如下代码: allprojects{

repositories{

maven{url "https://jitpack.io"}

}

}

在app级别的build.gradle中添加如下代码: dependencies{

compile 'com.github.PhilJay:MPAndroidChart:v3.0.1'

}

然后,编译项目即可。

二、MPAndroidChart使用方式概述(参见MPAndroidChart的git网站的Wiki):1、创建Chart使用LineChart, BarChart, PieChart或CombineChart时需要先在布局文件中进行定义,然后在后台代码中绑定;或者直接在代码中声明也行(不常用)。

2、设置Chart的样式当创建好一个chart后,就可以为该chart设置样式,包括chart的放缩,chart视图窗口的边距和加载动画,X/Y轴标签的样式、显示的位置、坐标轴的宽度、是否可用等,图例的位置、文字大小等等 。

lineChart.getDescription().setEnabled(false);//设置描述 lineChart.setPinchZoom(true);//设置按比例放缩柱状图

//x坐标轴设置 XAxis xAxis = lineChart.getXAxis(); xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//设置X轴标签显示位置 xAxis.setDrawGridLines(false);//不绘制格网线 xAxis.setGranularity(1f);//设置最小间隔,防止当放大时,出现重复标签。 xAxis.setLabelCount(12);//设置x轴显示的标签个数 xAxis.setAxisLineWidth(2f);//设置x轴宽度, ...其他样式

//y轴设置 YAxis leftAxis = lineChart.getAxisLeft();//取得左侧y轴 leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);//y轴标签绘制的位置 leftAxis.setDrawGridLines(false);//不绘制y轴格网线 leftAxis.setDrawLabels(false);//不显示坐标轴上的值, ...其他样式

lineChart.getAxisRight().setEnabled(false);

//图例设置 Legend legend = lineChart.getLegend(); legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER); legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); legend.setOrientation(Legend.LegendOrientation.HORIZONTAL); legend.setDrawInside(false); legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT); legend.setForm(Legend.LegendForm.LINE); legend.setTextSize(12f);//设置图例字体大小, ...其他样式

lineChart.setExtraOffsets(10, 30, 20, 10);//设置视图窗口大小 lineChart.animateX(1500);//数据显示动画,从左往右依次显示

3、添加数据当设置好一个chart的样式后,就可以为该chart添加数据。例如LineChart,一个Entry类代表图上的一个(x,y)坐标对。但在其他的chart类型中,例如BarChart,则是BarEntry类代表 图上的一个(x,y)坐标对。

YourData[] dataObjects = ...; List<Entry> entries = new ArrayList<Entry>(); for (YourData data : dataObjects) { // turn your data into Entry objects entries.add(new Entry(data.getValueX(), data.getValueY())); }

用List<Entry>初始化一个LineDataSet对象以代表该数据集。如果一个LineChart有多个LineDataSet,每个LineDataSet可以设置自己的样式。

LineDataSet dataSet = new LineDataSet(entries, "Label"); // add entries to dataset

dataSet.setColor(...);

dataSet.setValueTextColor(...); // styling, ...

然后,将LineDataSet添加到LineData对象中。LineData对象持有LineChart的所有数据,并允许设置额外的样式。最后,将LineData对象设置到LineChart并刷新该LineChart即可。

ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>(); dataSets.add(dataSet); // add the datasets ...other add

LineData lineData = new LineData(dataSets); chart.setData(lineData); chart.setValueTextSize(10f);//设置数值字体大小, ...other styling chart.invalidate(); // refresh

三、利用MPAndroidChart绘制柱状图、线图、饼图和组合图,测试设备为360N4S。项目结构如下图所示:(一)MainActivity的代码如下: 布局文件:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="/apk/res/android" xmlns:tools="/tools" android:id="@+id/activity_main" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.charlie.mpandroidcharttest.MainActivity">

<ListView android:id="@+id/listview" android:layout_width="match_parent" android:layout_height="match_parent"></ListView> </RelativeLayout>

代码文件:

package com.charlie.mpandroidcharttest;

import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView;

import com.charlie.mpandroidcharttest.chartactivity.BarChartActivity; import com.charlie.bineChartActivity; import com.charlie.mpandroidcharttest.chartactivity.LineChartActivity; import com.charlie.mpandroidcharttest.chartactivity.MultiLineChartActivity; import com.charlie.mpandroidcharttest.chartactivity.PieChartActivity; import com.charlie.mpandroidcharttest.chartactivity.PositiveNegativeBarChartActivity; import com.charlie.mpandroidcharttest.chartactivity.ThreeBarChartActivity; import com.charlie.mpandroidcharttest.chartactivity.TwoBarChartActivity;

import java.util.ArrayList; import java.util.List;

public class MainActivity extends AppCompatActivity implements AdapterView.OnItemClickListener {

private ListView listView; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main);

listView=(ListView)findViewById(R.id.listview); listView.setAdapter(new ArrayAdapter<>(this,android.R.layout.simple_list_item_1,initListData())); listView.setOnItemClickListener(this); }

private List<String> initListData(){ List<String> data = new ArrayList<>(); data.add("柱状图(单)"); data.add("柱状图(双)"); data.add("柱状图(三)"); data.add("正负柱状图"); data.add("折线图(单)"); data.add("折线图(复)"); data.add("饼图"); data.add("组合图"); return data; }

@Override public void onItemClick(AdapterView<?> parent, View view, int position, long id) { Intent i; switch (position){ case 0: i = new Intent(MainActivity.this, BarChartActivity.class); startActivity(i); break; case 1: i = new Intent(MainActivity.this, TwoBarChartActivity.class); startActivity(i); break; case 2: i = new Intent(MainActivity.this, ThreeBarChartActivity.class); startActivity(i); break; case 3: i = new Intent(MainActivity.this, PositiveNegativeBarChartActivity.class); startActivity(i); break; case 4: i = new Intent(MainActivity.this, LineChartActivity.class); startActivity(i); break; case 5: i = new Intent(MainActivity.this, MultiLineChartActivity.class); startActivity(i); break; case 6: i = new Intent(MainActivity.this, PieChartActivity.class); startActivity(i); break; case 7: i = new Intent(MainActivity.this, CombineChartActivity.class); startActivity(i); break; } } }

(二)柱状图(包括单柱图、双柱图、三柱图和正负柱图): 1、单柱图: 先看效果图,如下:

布局如下:<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="/apk/res/android" xmlns:tools="/tools" android:id="@+id/activity_bar_chart" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.charlie.mpandroidcharttest.chartactivity.BarChartActivity"> <com.github.mikephil.charting.charts.BarChart android:id="@+id/barChart1" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>

设置好x轴和y轴要显示的数据,然后调用如下函数即可:

/** * 单数据集。设置柱状图样式,X轴为字符串,Y轴为数值 *

* @param barChart * @param xAxisValue

* @param yAxisValue

* @param title 图例文字

* @param xAxisTextSize x轴标签字体大小

* @param barColor

*/

public static void setBarChart(BarChart barChart, List<String> xAxisValue, List<Float> yAxisValue, String title, float xAxisTextSize, Integer barColor) { barChart.getDescription().setEnabled(false);//设置描述 barChart.setPinchZoom(true);//设置按比例放缩柱状图

//设置自定义的markerView MPChartMarkerView markerView = new MPChartMarkerView(barChart.getContext(), R.layout.custom_marker_view); barChart.setMarker(markerView);

//x坐标轴设置 IAxisValueFormatter xAxisFormatter = new StringAxisValueFormatter(xAxisValue);//设置自定义的x轴值格式化器 XAxis xAxis = barChart.getXAxis();//获取x轴 xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);//设置X轴标签显示位置 xAxis.setDrawGridLines(false);//不绘制格网线 xAxis.setGranularity(1f);//设置最小间隔,防止当放大时,出现重复标签。 xAxis.setValueFormatter(xAxisFormatter); xAxis.setTextSize(xAxisTextSize);//设置标签字体大小 xAxis.setLabelCount(xAxisValue.size());//设置标签显示的个数

//y轴设置 YAxis leftAxis = barChart.getAxisLeft();//获取左侧y轴 leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);//设置y轴标签显示在外侧 leftAxis.setAxisMinimum(0f);//设置Y轴最小值 leftAxis.setDrawGridLines(false); leftAxis.setDrawLabels(false);//禁止绘制y轴标签 leftAxis.setDrawAxisLine(false);//禁止绘制y轴

barChart.getAxisRight().setEnabled(false);//禁用右侧y轴

//图例设置 Legend legend = barChart.getLegend(); legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);//图例水平居中 legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);//图例在图表上方 legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);//图例的方向为水平 legend.setDrawInside(false);//绘制在chart的外侧 legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);//图例中的文字方向

legend.setForm(Legend.LegendForm.SQUARE);//图例窗体的形状 legend.setFormSize(0f);//图例窗体的大小 legend.setTextSize(16f);//图例文字的大小 //legend.setYOffset(-2f);

//设置柱状图数据 setBarChartData(barChart, yAxisValue, title, barColor);

barChart.setExtraBottomOffset(10);//距视图窗口底部的偏移,类似与paddingbottom barChart.setExtraTopOffset(30);//距视图窗口顶部的偏移,类似与paddingtop barChart.setFitBars(true);//使两侧的柱图完全显示 barChart.animateX(1500);//数据显示动画,从左往右依次显示 }

/** * 设置柱图 *

* @param barChart * @param yAxisValue

* @param title

* @param barColor

*/

private static void setBarChartData(BarChart barChart, List<Float> yAxisValue, String title, Integer barColor) {

ArrayList<BarEntry> entries = new ArrayList<>();

for (int i = 0, n = yAxisValue.size(); i < n; ++i) { entries.add(new BarEntry(i, yAxisValue.get(i))); }

BarDataSet set1;

if (barChart.getData() != null && barChart.getData().getDataSetCount() > 0) { set1 = (BarDataSet) barChart.getData().getDataSetByIndex(0); set1.setValues(entries); barChart.getData().notifyDataChanged(); barChart.notifyDataSetChanged(); } else { set1 = new BarDataSet(entries, title); if (barColor == null) { set1.setColor(ContextCompat.getColor(barChart.getContext(), R.color.bar));//设置set1的柱的颜色 } else { set1.setColor(barColor); }

ArrayList<IBarDataSet> dataSets = new ArrayList<>(); dataSets.add(set1);

BarData data = new BarData(dataSets); data.setValueTextSize(10f); data.setBarWidth(0.9f); data.setValueFormatter(new MyValueFormatter());

barChart.setData(data); } }

自定义MPChartMarkerView的代码如下:

package com.mon;

import android.content.Context;

import com.charlie.mpandroidcharttest.R; import com.charlie.mpandroidcharttest.util.StringUtils; import com.github.ponents.MarkerView; import com.github.mikephil.charting.data.CandleEntry; import com.github.mikephil.charting.data.Entry; import com.github.mikephil.charting.highlight.Highlight; import com.github.mikephil.charting.utils.MPPointF;

/** * Created by JKWANG-PC on /11/1. * * Since release v3.0.0, markers (popup views) in the chart are represented by the IMarker interface. */

public class MPChartMarkerView extends MarkerView {

private ArrowTextView tvContent;

/** * Constructor. Sets up the MarkerView with a custom layout resource. * * @param context * @param layoutResource the layout resource to use for the MarkerView */ public MPChartMarkerView(Context context, int layoutResource) { super(context, layoutResource);

tvContent = (ArrowTextView) findViewById(R.id.tvContent); }

@Override public void refreshContent(Entry e, Highlight highlight) { if (e instanceof CandleEntry) {

CandleEntry ce = (CandleEntry) e;

tvContent.setText(StringUtils.double2String(ce.getHigh(), 2)); } else {

tvContent.setText(StringUtils.double2String(e.getY(), 2)); }

super.refreshContent(e, highlight);//必须加上该句话;This sentence must be added. }

private MPPointF mOffset;

@Override public MPPointF getOffset() { if(mOffset == null) { // center the marker horizontally and vertically mOffset = new MPPointF(-(getWidth() / 2), -getHeight()); }

return mOffset; } }

自定义ArrowTextView的代码如下:

package com.mon;

import android.content.Context; import android.content.res.TypedArray; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Path; import android.graphics.RectF; import android.util.AttributeSet; import android.util.TypedValue; import android.widget.TextView;

import com.charlie.mpandroidcharttest.R;

/** * Created by JKWANG-PC on /11/1. * 带下箭头的文本框。 */

public class ArrowTextView extends TextView {

private float radius; private float arrowWidth; private float arrowHeight; private int color;

public ArrowTextView(Context context, AttributeSet attrs) { super(context, attrs); ini(context, attrs); }

private void ini(Context context, AttributeSet attrs) { TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.ArrowTextView); radius = typedArray.getDimension(R.styleable.ArrowTextView_radius, 0); arrowWidth = typedArray.getDimension(R.styleable.ArrowTextView_arrowWidth, 0); arrowHeight = typedArray.getDimension(R.styleable.ArrowTextView_arrowHeight, 0); color = typedArray.getColor(R.styleable.ArrowTextView_bg, Color.RED); }

public ArrowTextView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); ini(context, attrs); }

public ArrowTextView(Context context) { super(context); }

/** * @param arrowWidth 三角形箭头的宽度....... */ public void setArrowWidth(float arrowWidth) { this.arrowWidth = arrowWidth; invalidate();

}

/** * @param arrowHeight 三角形箭头的高度...... */ public void setArrowHeight(float arrowHeight) { this.arrowHeight = arrowHeight; invalidate(); }

/** * @param radius 矩形四角圆角的半径.......... */ public void setRadius(float radius) { this.radius = radius; invalidate();

}

/** * @param color 箭头矩形的背景色......... */ public void setBgColor(int color) { this.color = color; invalidate();

}

@Override protected void onDraw(Canvas canvas) { Paint paint = new Paint(); paint.setColor(color == 0 ? Color.RED : color); paint.setAntiAlias(true); if (radius == 0) { radius = TypedValue.applyDimension(PLEX_UNIT_PX, 5, getResources().getDisplayMetrics()); } if (arrowWidth == 0) { arrowWidth = TypedValue.applyDimension(PLEX_UNIT_PX, 20, getResources().getDisplayMetrics()); } if (arrowHeight == 0) { arrowHeight = TypedValue.applyDimension(PLEX_UNIT_PX, 15, getResources().getDisplayMetrics()); } //带圆角的矩形(下边减去三角形的高度...........) int width = getWidth(); Float height = getHeight() - arrowHeight; canvas.drawRoundRect(new RectF(0, 0, getWidth(), height), radius, radius, paint);

//画三角形 Path path = new Path(); path.setFillType(Path.FillType.EVEN_ODD); float xMiddle = width / 2; float xLeft = xMiddle - arrowWidth / 2; float xRight = xMiddle + arrowWidth / 2; float yBottom = height + arrowHeight; path.moveTo(xMiddle, yBottom); path.lineTo(xLeft, height-1); path.lineTo(xRight, height-1); path.lineTo(xMiddle, yBottom); path.close(); canvas.drawPath(path, paint); // canvas.restore(); // canvas.translate(left, 0); super.onDraw(canvas); } }

attrs.xml内容如下:

<?xml version="1.0" encoding="utf-8"?> <resources>

<declare-styleable name="ArrowTextView"> <attr name="radius" format="dimension" /> <attr name="arrowWidth" format="dimension" /> <attr name="arrowHeight" format="dimension" /> <attr name="bg" format="color" /> </declare-styleable> </resources>

colors.xml内容如下:

<?xml version="1.0" encoding="utf-8"?> <resources> <color name="bar">#6CB0DF</color> <color name="bar1">#B5C2CA</color> <color name="bar2">#F5E6BF</color> <color name="bar3">#81D8C8</color>

<color name="description">#686868</color>

<color name="line">#8CD276</color> <color name="linefill">#DEEFE4</color> <color name="line1">#E9C517</color> <color name="line1fill">#ECEAD0</color> <color name="line2">#9F8FBA</color> <color name="line2fill">#EBE4F8</color> </resources>

custom_marker_view.xml布局文件如下:

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="/apk/res/android" xmlns:app="/apk/res-auto" android:orientation="vertical" android:layout_width="wrap_content" android:layout_height="wrap_content"> <com.mon.ArrowTextView android:id="@+id/tvContent" android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center" android:paddingBottom="16px" android:paddingRight="5px" android:paddingLeft="5px" android:text="" android:textSize="36px" android:textColor="@color/description" android:maxLines="1" android:ellipsize="end" app:bg="@color/linefill" app:radius="5px"/> </LinearLayout>

MyValueFormatter.java定义如下:

package com.mon;

import com.charlie.mpandroidcharttest.util.StringUtils; import com.github.mikephil.charting.data.Entry; import com.github.mikephil.charting.formatter.IValueFormatter; import com.github.mikephil.charting.utils.ViewPortHandler;

/** * Created by JKWANG-PC on /11/21. */

public class MyValueFormatter implements IValueFormatter {

@Override public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { return StringUtils.double2String(value, 2); } }

StringAxisValueFormatter.java定义如下:

package com.mon;

import com.github.ponents.AxisBase; import com.github.mikephil.charting.formatter.IAxisValueFormatter;

import java.util.List;

/** * Created by Charlie on /9/23. * 对字符串类型的坐标轴标记进行格式化 */

public class StringAxisValueFormatter implements IAxisValueFormatter {

//区域值 private List<String> mStrs;

/** * 对字符串类型的坐标轴标记进行格式化 * @param strs */ public StringAxisValueFormatter(List<String> strs){ this.mStrs =strs; }

@Override public String getFormattedValue(float v, AxisBase axisBase) { return mStrs.get((int)v); } }

StringUtils.java定义如下:

package com.charlie.mpandroidcharttest.util;

import java.text.NumberFormat;

/** * Created by Charlie on /10/8. * 通用字符串管理类 */

public class StringUtils {

/** * 将double转为数值,并最多保留num位小数。例如当num为2时,1.268为1.27,1.2仍为1.2;1仍为1,而非1.00;100.00则返回100。 * * @param d * @param num 小数位数 * @return */ public static String double2String(double d, int num) { NumberFormat nf = NumberFormat.getNumberInstance(); nf.setMaximumFractionDigits(num);//保留两位小数 nf.setGroupingUsed(false);//去掉数值中的千位分隔符

String temp = nf.format(d); if (temp.contains(".")) { String s1 = temp.split("\\.")[0]; String s2 = temp.split("\\.")[1]; for (int i = s2.length(); i > 0; --i) { if (!s2.substring(i - 1, i).equals("0")) { return s1 + "." + s2.substring(0, i); } } return s1; } return temp; }

/** * 将double转为数值,并最多保留num位小数。 * * @param d * @param num 小数个数 * @param defValue 默认值。当d为null时,返回该值。 * @return */ public static String double2String(Double d, int num, String defValue){ if(d==null){ return defValue; }

return double2String(d,num); } }

2、双柱图: 先看效果图,如下:

布局同1单柱图。设置好x轴和y轴要显示的数据,然后调用如下函数即可:

/** * 设置双柱状图样式 *

* @param barChart * @param xAxisValue

* @param yAxisValue1

* @param yAxisValue2

* @param bartilte1

* @param bartitle2

*/

public static void setTwoBarChart(BarChart barChart, List<Integer> xAxisValue, List<Float> yAxisValue1, List<Float> yAxisValue2, String bartilte1, String bartitle2) { barChart.getDescription().setEnabled(false);//设置描述 barChart.setPinchZoom(true);//设置按比例放缩柱状图 barChart.setExtraBottomOffset(10); barChart.setExtraTopOffset(30);

MPChartMarkerView markerView = new MPChartMarkerView(barChart.getContext(), R.layout.custom_marker_view); barChart.setMarker(markerView);

//x坐标轴设置 XAxis xAxis = barChart.getXAxis(); xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); xAxis.setDrawGridLines(false); xAxis.setGranularity(1f); xAxis.setLabelCount(xAxisValue.size()); xAxis.setCenterAxisLabels(true);//设置标签居中 xAxis.setValueFormatter(new IAxisValueFormatter() { @Override public String getFormattedValue(float v, AxisBase axisBase) { return String.valueOf((int) v); } });

//y轴设置 YAxis leftAxis = barChart.getAxisLeft(); leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART); leftAxis.setDrawGridLines(false); leftAxis.setDrawLabels(false); leftAxis.setDrawAxisLine(false);

//设置坐标轴最大最小值 Float yMin1 = Collections.min(yAxisValue1); Float yMin2 = Collections.min(yAxisValue2); Float yMax1 = Collections.max(yAxisValue1); Float yMax2 = Collections.max(yAxisValue2); Float yMin = Double.valueOf((yMin1 < yMin2 ? yMin1 : yMin2) * 0.1).floatValue(); Float yMax = Double.valueOf((yMax1 > yMax2 ? yMax1 : yMax2) * 1.1).floatValue(); leftAxis.setAxisMaximum(yMax); leftAxis.setAxisMinimum(yMin);

barChart.getAxisRight().setEnabled(false);

//图例设置 Legend legend = barChart.getLegend(); legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER); legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); legend.setOrientation(Legend.LegendOrientation.HORIZONTAL); legend.setDrawInside(false); legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT); legend.setForm(Legend.LegendForm.SQUARE); legend.setTextSize(12f);

//设置柱状图数据 setTwoBarChartData(barChart, xAxisValue, yAxisValue1, yAxisValue2, bartilte1, bartitle2);

barChart.animateX(1500);//数据显示动画,从左往右依次显示 barChart.invalidate(); }

/** * 设置柱状图数据源 */

private static void setTwoBarChartData(BarChart barChart, List<Integer> xAxisValue, List<Float> yAxisValue1, List<Float> yAxisValue2, String bartilte1, String bartitle2) { float groupSpace = 0.04f; float barSpace = 0.03f; float barWidth = 0.45f; // (0.45 + 0.03) * 2 + 0.04 = 1,即一个间隔为一组,包含两个柱图 -> interval per "group"

ArrayList<BarEntry> entries1 = new ArrayList<>(); ArrayList<BarEntry> entries2 = new ArrayList<>();

for (int i = 0, n = yAxisValue1.size(); i < n; ++i) { entries1.add(new BarEntry(xAxisValue.get(i), yAxisValue1.get(i))); entries2.add(new BarEntry(xAxisValue.get(i), yAxisValue2.get(i))); }

BarDataSet dataset1, dataset2;

if (barChart.getData() != null && barChart.getData().getDataSetCount() > 0) { dataset1 = (BarDataSet) barChart.getData().getDataSetByIndex(0); dataset2 = (BarDataSet) barChart.getData().getDataSetByIndex(1); dataset1.setValues(entries1); dataset2.setValues(entries2); barChart.getData().notifyDataChanged(); barChart.notifyDataSetChanged(); } else { dataset1 = new BarDataSet(entries1, bartilte1); dataset2 = new BarDataSet(entries2, bartitle2);

dataset1.setColor(Color.rgb(129, 216, 200)); dataset2.setColor(Color.rgb(181, 194, 202));

ArrayList<IBarDataSet> dataSets = new ArrayList<>(); dataSets.add(dataset1); dataSets.add(dataset2);

BarData data = new BarData(dataSets); data.setValueTextSize(10f); data.setBarWidth(0.9f); data.setValueFormatter(new IValueFormatter() { @Override public String getFormattedValue(float value, Entry entry, int i, ViewPortHandler viewPortHandler) { return StringUtils.double2String(value, 2); } });

barChart.setData(data); }

barChart.getBarData().setBarWidth(barWidth); barChart.getXAxis().setAxisMinimum(xAxisValue.get(0)); // barData.getGroupWith(...) is a helper that calculates the width each group needs based on the provided parameters barChart.getXAxis().setAxisMaximum(barChart.getBarData().getGroupWidth(groupSpace, barSpace) * xAxisValue.size() + xAxisValue.get(0)); barChart.groupBars(xAxisValue.get(0), groupSpace, barSpace); }

3、三柱图: 先看效果图,如下:

布局同1单柱图。设置好x轴和y轴要显示的数据,然后调用如下函数即可:

/** * 设置三柱状图样式 *

* @param barChart * @param xAxisValue

* @param yAxisValue1

* @param yAxisValue2

* @param yAxisValue3

* @param bartilte1

* @param bartitle2

* @param bartitle3

*/

public static void setThreeBarChart(BarChart barChart, List<Integer> xAxisValue, List<Float> yAxisValue1, List<Float> yAxisValue2, List<Float> yAxisValue3, String bartilte1, String bartitle2, String bartitle3) { barChart.getDescription().setEnabled(false);//设置描述 barChart.setPinchZoom(false);//设置不按比例放缩柱状图 barChart.setExtraBottomOffset(10); barChart.setExtraTopOffset(30);

MPChartMarkerView markerView = new MPChartMarkerView(barChart.getContext(), R.layout.custom_marker_view); barChart.setMarker(markerView);

//x坐标轴设置 XAxis xAxis = barChart.getXAxis(); xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); xAxis.setGranularity(1f); xAxis.setLabelCount(xAxisValue.size()); xAxis.setCenterAxisLabels(true); xAxis.setDrawGridLines(false); xAxis.setValueFormatter(new IAxisValueFormatter() { @Override public String getFormattedValue(float v, AxisBase axisBase) { return String.valueOf((int) v); } });

//y轴设置 YAxis leftAxis = barChart.getAxisLeft(); leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART); leftAxis.setDrawGridLines(false); leftAxis.setDrawLabels(false); leftAxis.setDrawAxisLine(false);

Float yMin1 = Collections.min(yAxisValue1); Float yMin2 = Collections.min(yAxisValue2); Float yMin3 = Collections.min(yAxisValue3); Float yMax1 = Collections.max(yAxisValue1); Float yMax2 = Collections.max(yAxisValue2); Float yMax3 = Collections.max(yAxisValue3); Float yMinTemp = yMin1 < yMin2 ? yMin1 : yMin2; Float yMin = yMinTemp < yMin3 ? yMinTemp : yMin3; Float yMaxTemp = yMax1 > yMax2 ? yMax1 : yMax2; Float yMax = yMaxTemp > yMax3 ? yMaxTemp : yMax3; leftAxis.setAxisMinimum(Double.valueOf(yMin * 0.9).floatValue()); leftAxis.setAxisMaximum(Double.valueOf(yMax * 1.1).floatValue());

barChart.getAxisRight().setEnabled(false);

//图例设置 Legend legend = barChart.getLegend(); legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER); legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); legend.setOrientation(Legend.LegendOrientation.HORIZONTAL); legend.setDrawInside(false); legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT); legend.setForm(Legend.LegendForm.SQUARE); legend.setTextSize(12f);

//设置柱状图数据 setThreeBarChartData(barChart, xAxisValue, yAxisValue1, yAxisValue2, yAxisValue3, bartilte1, bartitle2, bartitle3);

barChart.animateX(1500);//数据显示动画,从左往右依次显示 barChart.invalidate(); }

/** * 设置三柱图数据源 *

* @param barChart * @param xAxisValue

* @param yAxisValue1

* @param yAxisValue2

* @param yAxisValue3

* @param bartilte1

* @param bartitle2

* @param bartitle3

*/

private static void setThreeBarChartData(BarChart barChart, List<Integer> xAxisValue, List<Float> yAxisValue1, List<Float> yAxisValue2, List<Float> yAxisValue3, String bartilte1, String bartitle2, String bartitle3) { float groupSpace = 0.04f; float barSpace = 0.02f; float barWidth = 0.3f; // (0.3 + 0.02) * 3 + 0.04 = 1,即一个间隔为一组,包含三个柱图 -> interval per "group"

ArrayList<BarEntry> first_entries = new ArrayList<>(); ArrayList<BarEntry> second_entries = new ArrayList<>(); ArrayList<BarEntry> third_entries = new ArrayList<>();

for (int i = 0, n = xAxisValue.size(); i < n; ++i) { first_entries.add(new BarEntry(xAxisValue.get(i), yAxisValue1.get(i))); second_entries.add(new BarEntry(xAxisValue.get(i), yAxisValue2.get(i))); third_entries.add(new BarEntry(xAxisValue.get(i), yAxisValue3.get(i))); }

BarDataSet first_set, second_set, third_set;

if (barChart.getData() != null && barChart.getData().getDataSetCount() > 0) { first_set = (BarDataSet) barChart.getData().getDataSetByIndex(0); second_set = (BarDataSet) barChart.getData().getDataSetByIndex(1); third_set = (BarDataSet) barChart.getData().getDataSetByIndex(2); first_set.setValues(first_entries); second_set.setValues(second_entries); third_set.setValues(third_entries); barChart.getData().notifyDataChanged(); barChart.notifyDataSetChanged(); } else { first_set = new BarDataSet(first_entries, bartilte1); second_set = new BarDataSet(second_entries, bartitle2); third_set = new BarDataSet(third_entries, bartitle3);

first_set.setColor(ContextCompat.getColor(barChart.getContext(), R.color.bar1)); second_set.setColor(ContextCompat.getColor(barChart.getContext(), R.color.bar2)); third_set.setColor(ContextCompat.getColor(barChart.getContext(), R.color.bar3));

ArrayList<IBarDataSet> dataSets = new ArrayList<>(); dataSets.add(first_set); dataSets.add(second_set); dataSets.add(third_set);

BarData data = new BarData(dataSets); data.setValueTextSize(10f); data.setBarWidth(0.9f); data.setValueFormatter(new IValueFormatter() { @Override public String getFormattedValue(float value, Entry entry, int i, ViewPortHandler viewPortHandler) { return StringUtils.double2String(value, 2); } });

barChart.setData(data); }

barChart.getBarData().setBarWidth(barWidth); barChart.getXAxis().setAxisMinimum(xAxisValue.get(0)); barChart.getXAxis().setAxisMaximum(barChart.getBarData().getGroupWidth(groupSpace, barSpace) * xAxisValue.size() + xAxisValue.get(0)); barChart.groupBars(xAxisValue.get(0), groupSpace, barSpace); }

4、正负柱图:先看效果图,如下:

布局同1单柱图。设置好x轴和y轴要显示的数据,然后调用如下函数即可:

/** * 设置正负值在0轴上下方的柱图 *

* @param barChart * @param xAxisValue x轴的值。必须与yAxisValue的值个数相同

* @param yAxisValue y轴的值。必须与xAxisValue的值个数相同

* @param title

*/

public static void setPositiveNegativeBarChart(BarChart barChart, List<String> xAxisValue, List<Float> yAxisValue, String title) { barChart.setDrawBarShadow(false); barChart.setDrawValueAboveBar(true); barChart.getDescription().setEnabled(false); // scaling can now only be done on x- and y-axis separately barChart.setPinchZoom(false); barChart.setDrawGridBackground(false); barChart.setExtraBottomOffset(10); barChart.setExtraTopOffset(30);

MPChartMarkerView markerView = new MPChartMarkerView(barChart.getContext(), R.layout.custom_marker_view); barChart.setMarker(markerView);

XAxis xAxis = barChart.getXAxis(); xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); xAxis.setDrawGridLines(false); xAxis.setDrawAxisLine(false); xAxis.setTextColor(Color.DKGRAY); xAxis.setTextSize(13f); xAxis.setAxisMinimum(0f); xAxis.setAxisMaximum(xAxisValue.size()); xAxis.setLabelCount(xAxisValue.size()); xAxis.setCenterAxisLabels(true); xAxis.setGranularity(1f);

YAxis left = barChart.getAxisLeft(); left.setDrawLabels(false); left.setSpaceTop(25f); left.setSpaceBottom(25f); left.setDrawAxisLine(false); left.setDrawGridLines(false); left.setDrawZeroLine(true); // draw a zero line left.setZeroLineColor(Color.DKGRAY); left.setZeroLineWidth(1f); barChart.getAxisRight().setEnabled(false);

Legend legend = barChart.getLegend(); legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER); legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); legend.setOrientation(Legend.LegendOrientation.HORIZONTAL); legend.setDrawInside(false); legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);

legend.setForm(Legend.LegendForm.SQUARE); legend.setFormSize(0f); legend.setTextSize(16f); legend.setYOffset(-2f);

// THIS IS THE ORIGINAL DATA YOU WANT TO PLOT final List<Data> data = new ArrayList<>(); for (int i = 0, n = xAxisValue.size(); i < n; ++i) { data.add(new Data(0.5f + i, yAxisValue.get(i), xAxisValue.get(i))); }

xAxis.setValueFormatter(new IAxisValueFormatter() { @Override public String getFormattedValue(float value, AxisBase axis) { return data.get(Math.min(Math.max((int) value, 0), data.size() - 1)).xAxisValue; } });

setData(barChart, data, title); }

private static void setData(BarChart barChart, List<Data> dataList, String title) {

ArrayList<BarEntry> values = new ArrayList<BarEntry>(); List<Integer> colors = new ArrayList<Integer>();

int green = Color.rgb(195, 221, 155); int red = Color.rgb(237, 189, 189);

for (int i = 0; i < dataList.size(); i++) {

Data d = dataList.get(i); BarEntry entry = new BarEntry(d.xValue, d.yValue); values.add(entry);

// specific colors if (d.yValue >= 0) colors.add(red); else colors.add(green); }

BarDataSet set;

if (barChart.getData() != null && barChart.getData().getDataSetCount() > 0) { set = (BarDataSet) barChart.getData().getDataSetByIndex(0); set.setValues(values); barChart.getData().notifyDataChanged(); barChart.notifyDataSetChanged(); } else { set = new BarDataSet(values, title); set.setColors(colors); set.setValueTextColors(colors);

BarData data = new BarData(set); data.setValueTextSize(13f); data.setValueFormatter(new PositiveNegativeBarChartValueFormatter()); data.setBarWidth(0.8f);

barChart.setData(data); barChart.invalidate(); } }

/** * positive-negative data model representing data. */ private static class Data {

public String xAxisValue; public float yValue; public float xValue;

public Data(float xValue, float yValue, String xAxisValue) { this.xAxisValue = xAxisValue; this.yValue = yValue; this.xValue = xValue; } }

private static class PositiveNegativeBarChartValueFormatter implements IValueFormatter {

private DecimalFormat mFormattedStringCache;

public PositiveNegativeBarChartValueFormatter() { mFormattedStringCache = new DecimalFormat("######.00"); }

@Override public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { return mFormattedStringCache.format(value); } }

(三)折线图(包括单折线图、多折线图):1、单折线图: 先看效果图,如下:

布局如下:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="/apk/res/android" xmlns:tools="/tools" android:id="@+id/activity_line_chart" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.charlie.mpandroidcharttest.chartactivity.LineChartActivity"> <com.github.mikephil.charting.charts.LineChart android:id="@+id/lineChart" android:layout_width="match_parent" android:layout_height="match_parent"/> </RelativeLayout>

设置好x轴和y轴要显示的数据,然后调用函数setLineChart ()即可:

public static final int[] LINE_COLORS = { Color.rgb(140, 210, 118), Color.rgb(159, 143, 186), Color.rgb(233, 197, 23) };//绿色,紫色,黄色

public static final int[] LINE_FILL_COLORS = { Color.rgb(222, 239, 228), Color.rgb(246, 234, 208), Color.rgb(235, 228, 248) };

/** * 单线单y轴图。 *

* @param lineChart * @param xAxisValue

* @param yAxisValue

* @param title

* @param showSetValues 是否在折线上显示数据集的值。true为显示,此时y轴上的数值不可见,否则相反。

*/

public static void setLineChart(LineChart lineChart, List<String> xAxisValue, List<Float> yAxisValue, String title, boolean showSetValues) { List<List<Float>> entriesList = new ArrayList<>(); entriesList.add(yAxisValue);

List<String> titles = new ArrayList<>(); titles.add(title);

setLinesChart(lineChart, xAxisValue, entriesList, titles, showSetValues,null); }

/** * 绘制线图,默认最多绘制三种颜色。所有线均依赖左侧y轴显示。 *

* @param lineChart * @param xAxisValue x轴的轴

* @param yXAxisValues y轴的值

* @param titles 每一个数据系列的标题

* @param showSetValues 是否在折线上显示数据集的值。true为显示,此时y轴上的数值不可见,否则相反。

* @param lineColors 线的颜色数组。为null时取默认颜色,此时最多绘制三种颜色。

*/

public static void setLinesChart(LineChart lineChart, List<String> xAxisValue, List<List<Float>> yXAxisValues, List<String> titles, boolean showSetValues, int[] lineColors) { lineChart.getDescription().setEnabled(false);//设置描述 lineChart.setPinchZoom(true);//设置按比例放缩柱状图

MPChartMarkerView markerView = new MPChartMarkerView(lineChart.getContext(), R.layout.custom_marker_view); lineChart.setMarker(markerView);

//x坐标轴设置 IAxisValueFormatter xAxisFormatter = new StringAxisValueFormatter(xAxisValue); XAxis xAxis = lineChart.getXAxis(); xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); xAxis.setDrawGridLines(false); xAxis.setGranularity(1f); xAxis.setLabelCount(xAxisValue.size()); /*xAxis.setAxisLineWidth(2f);*/ xAxis.setValueFormatter(xAxisFormatter);

//y轴设置 YAxis leftAxis = lineChart.getAxisLeft(); leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART); leftAxis.setDrawGridLines(false); if (showSetValues) { leftAxis.setDrawLabels(false);//折线上显示值,则不显示坐标轴上的值 } //leftAxis.setDrawZeroLine(true); /*leftAxis.setAxisMinimum(0f);*/ /*leftAxis.setAxisLineWidth(2f);*/

lineChart.getAxisRight().setEnabled(false);

//图例设置 Legend legend = lineChart.getLegend(); legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER); legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); legend.setOrientation(Legend.LegendOrientation.HORIZONTAL); legend.setDrawInside(false); legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT); legend.setForm(Legend.LegendForm.LINE); legend.setTextSize(12f);

//设置折线图数据 setLinesChartData(lineChart, yXAxisValues, titles, showSetValues,lineColors);

lineChart.setExtraOffsets(10, 30, 20, 10); lineChart.animateX(1500);//数据显示动画,从左往右依次显示 }

private static void setLinesChartData(LineChart lineChart, List<List<Float>> yXAxisValues, List<String> titles, boolean showSetValues, int[] lineColors) {

List<List<Entry>> entriesList = new ArrayList<>(); for (int i = 0; i < yXAxisValues.size(); ++i) { ArrayList<Entry> entries = new ArrayList<>(); for (int j = 0, n = yXAxisValues.get(i).size(); j < n; j++) { entries.add(new Entry(j, yXAxisValues.get(i).get(j))); } entriesList.add(entries); }

if (lineChart.getData() != null && lineChart.getData().getDataSetCount() > 0) {

for (int i = 0; i < lineChart.getData().getDataSetCount(); ++i) { LineDataSet set = (LineDataSet) lineChart.getData().getDataSetByIndex(i); set.setValues(entriesList.get(i)); set.setLabel(titles.get(i)); }

lineChart.getData().notifyDataChanged(); lineChart.notifyDataSetChanged(); } else { ArrayList<ILineDataSet> dataSets = new ArrayList<>();

for (int i = 0; i < entriesList.size(); ++i) { LineDataSet set = new LineDataSet(entriesList.get(i), titles.get(i)); if(lineColors!=null){ set.setColor(lineColors[i % entriesList.size()]); set.setCircleColor(lineColors[i % entriesList.size()]); set.setCircleColorHole(Color.WHITE); } else { set.setColor(LINE_COLORS[i % 3]); set.setCircleColor(LINE_COLORS[i % 3]); set.setCircleColorHole(Color.WHITE); }

if (entriesList.size() == 1) { set.setDrawFilled(true); set.setFillColor(LINE_FILL_COLORS[i % 3]); } dataSets.add(set); }

LineData data = new LineData(dataSets); if (showSetValues) { data.setValueTextSize(10f); data.setValueFormatter(new IValueFormatter() { @Override public String getFormattedValue(float value, Entry entry, int i, ViewPortHandler viewPortHandler) { return StringUtils.double2String(value, 1); } }); } else { data.setDrawValues(false); }

lineChart.setData(data); } }

2、多折线图:以三条线为例,先看效果图,如下:

布局同单线图,设置好x轴和y轴要显示的数据,然后调用函数setLinesChart()即可。

(四)饼图:先看效果图,如下:

布局如下:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="/apk/res/android" xmlns:tools="/tools" android:id="@+id/activity_pie_chart" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.charlie.mpandroidcharttest.chartactivity.PieChartActivity"> <com.github.mikephil.charting.charts.PieChart android:id="@+id/pieChart" android:layout_width="match_parent" android:layout_height="match_parent"></com.github.mikephil.charting.charts.PieChart> </RelativeLayout>

设置好x轴和y轴要显示的数据,然后调用如下函数即可:

public static final int[] PIE_COLORS = { Color.rgb(181, 194, 202), Color.rgb(129, 216, 200), Color.rgb(241, 214, 145), Color.rgb(108, 176, 223), Color.rgb(195, 221, 155), Color.rgb(251, 215, 191), Color.rgb(237, 189, 189), Color.rgb(172, 217, 243) };

/** * 设置饼图样式 *

* @param pieChart * @param pieValues

* @param title

* @param showLegend 是否显示图例

*/

public static void setPieChart(PieChart pieChart, Map<String, Float> pieValues, String title, boolean showLegend) { pieChart.setUsePercentValues(true);//设置使用百分比 pieChart.getDescription().setEnabled(false);//设置描述 pieChart.setExtraOffsets(20, 15, 20, 15); pieChart.setCenterText(title);//设置环中的文字 pieChart.setCenterTextSize(22f);//设置环中文字的大小 pieChart.setDrawCenterText(true);//设置绘制环中文字 pieChart.setRotationAngle(120f);//设置旋转角度

//图例设置 Legend legend = pieChart.getLegend(); if (showLegend) { legend.setEnabled(true); legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER); legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); legend.setOrientation(Legend.LegendOrientation.HORIZONTAL); legend.setDrawInside(false); legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT); } else { legend.setEnabled(false); }

//设置饼图数据 setPieChartData(pieChart, pieValues);

pieChart.animateX(1500, Easing.EasingOption.EaseInOutQuad);//数据显示动画 }

/** * 设置饼图数据源 */

private static void setPieChartData(PieChart pieChart, Map<String, Float> pieValues) { ArrayList<PieEntry> entries = new ArrayList<>();

Set set = pieValues.entrySet(); Iterator it = set.iterator(); while (it.hasNext()) { Map.Entry entry = (Map.Entry) it.next(); entries.add(new PieEntry(Float.valueOf(entry.getValue().toString()), entry.getKey().toString())); }

PieDataSet dataSet = new PieDataSet(entries, ""); dataSet.setSliceSpace(3f);//设置饼块之间的间隔 dataSet.setSelectionShift(5f);//设置饼块选中时偏离饼图中心的距离

dataSet.setColors(PIE_COLORS);//设置饼块的颜色 dataSet.setValueLinePart1OffsetPercentage(80f);//数据连接线距图形片内部边界的距离,为百分数 dataSet.setValueLinePart1Length(0.3f); dataSet.setValueLinePart2Length(0.4f); dataSet.setValueLineColor(Color.BLUE);//设置连接线的颜色 dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);

PieData pieData = new PieData(dataSet); pieData.setValueFormatter(new PercentFormatter()); pieData.setValueTextSize(11f); pieData.setValueTextColor(Color.DKGRAY);

pieChart.setData(pieData); pieChart.highlightValues(null); pieChart.invalidate(); }

(五)组合图:以线柱图为例,先看效果图,如下:

布局如下:

<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android="/apk/res/android" xmlns:tools="/tools" android:id="@+id/activity_combine_chart" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="com.charlie.bineChartActivity"> <com.github.mikephil.binedChart android:id="@+id/combineChart" android:layout_width="match_parent" android:layout_height="match_parent"></com.github.mikephil.binedChart> </RelativeLayout>

设置好x轴和y轴要显示的数据,然后调用如下函数即可:

/** * 设置柱线组合图样式,柱图依赖左侧y轴,线图依赖右侧y轴 */

public static void setCombineChart(CombinedChart combineChart, final List<String> xAxisValues, List<Float> lineValues, List<Float> barValues, String lineTitle, String barTitle) { combineChart.getDescription().setEnabled(false);//设置描述 combineChart.setPinchZoom(true);//设置按比例放缩柱状图

MPChartMarkerView markerView = new MPChartMarkerView(combineChart.getContext(), R.layout.custom_marker_view); combineChart.setMarker(markerView);

//设置绘制顺序,让线在柱的上层 combineChart.setDrawOrder(new CombinedChart.DrawOrder[]{ CombinedChart.DrawOrder.BAR, CombinedChart.DrawOrder.LINE });

//x坐标轴设置 XAxis xAxis = combineChart.getXAxis(); xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); xAxis.setDrawGridLines(false); xAxis.setGranularity(1f); xAxis.setLabelCount(xAxisValues.size() + 2); xAxis.setValueFormatter(new IAxisValueFormatter() { @Override public String getFormattedValue(float v, AxisBase axisBase) { if (v < 0 || v > (xAxisValues.size() - 1))//使得两侧柱子完全显示 return ""; return xAxisValues.get((int) v); } });

//y轴设置 YAxis leftAxis = combineChart.getAxisLeft(); leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART); leftAxis.setDrawGridLines(false); /*leftAxis.setAxisMinimum(0f);*/

Float yMin = Double.valueOf(Collections.min(barValues) * 0.9).floatValue(); Float yMax = Double.valueOf(Collections.max(barValues) * 1.1).floatValue(); leftAxis.setAxisMaximum(yMax); leftAxis.setAxisMinimum(yMin);

YAxis rightAxis = combineChart.getAxisRight(); rightAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART); rightAxis.setDrawGridLines(false);

//图例设置 Legend legend = combineChart.getLegend(); legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER); legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP); legend.setOrientation(Legend.LegendOrientation.HORIZONTAL); legend.setDrawInside(false); legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT); legend.setForm(Legend.LegendForm.SQUARE); legend.setTextSize(12f);

//设置组合图数据 CombinedData data = new CombinedData(); data.setData(generateLineData(lineValues, lineTitle)); data.setData(generateBarData(barValues, barTitle));

combineChart.setData(data);//设置组合图数据源

//使得两侧柱子完全显示 xAxis.setAxisMinimum(combineChart.getCombinedData().getXMin() - 1f); xAxis.setAxisMaximum(combineChart.getCombinedData().getXMax() + 1f);

combineChart.setExtraTopOffset(30); combineChart.setExtraBottomOffset(10); combineChart.animateX(1500);//数据显示动画,从左往右依次显示 combineChart.invalidate(); }

/** * 生成线图数据 */

private static LineData generateLineData(List<Float> lineValues, String lineTitle) { ArrayList<Entry> lineEntries = new ArrayList<>();

for (int i = 0, n = lineValues.size(); i < n; ++i) { lineEntries.add(new Entry(i, lineValues.get(i))); }

LineDataSet lineDataSet = new LineDataSet(lineEntries, lineTitle); lineDataSet.setColor(Color.rgb(233, 196, 21)); lineDataSet.setLineWidth(2.5f);//设置线的宽度 lineDataSet.setCircleColor(Color.rgb(244, 219, 100));//设置圆圈的颜色 lineDataSet.setCircleColorHole(Color.WHITE);//设置圆圈内部洞的颜色 //lineDataSet.setValueTextColor(Color.rgb(254,116,139)); lineDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT);//设置线数据依赖于右侧y轴 lineDataSet.setDrawValues(false);//不绘制线的数据

LineData lineData = new LineData(lineDataSet); lineData.setValueTextSize(10f); lineData.setValueFormatter(new IValueFormatter() { @Override public String getFormattedValue(float value, Entry entry, int i, ViewPortHandler viewPortHandler) { return StringUtils.double2String(value, 2); } });

return lineData; }

/** * 生成柱图数据 *

* @param barValues * @return

*/

private static BarData generateBarData(List<Float> barValues, String barTitle) {

ArrayList<BarEntry> barEntries = new ArrayList<>();

for (int i = 0, n = barValues.size(); i < n; ++i) { barEntries.add(new BarEntry(i, barValues.get(i))); }

BarDataSet barDataSet = new BarDataSet(barEntries, barTitle); barDataSet.setColor(Color.rgb(159, 143, 186)); barDataSet.setValueTextColor(Color.rgb(159, 143, 186)); barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);

BarData barData = new BarData(barDataSet); barData.setValueTextSize(10f); barData.setBarWidth(0.9f); barData.setValueFormatter(new IValueFormatter() { @Override public String getFormattedValue(float value, Entry entry, int i, ViewPortHandler viewPortHandler) { return StringUtils.double2String(value, 2); } });

return barData; }

总结 1、MPAndroidChart各种Chart有一定的类似,只要把一个搞懂了其它的差不多。 2、使用chart时,一般都要经过以下几个步骤:(1)定义该chart;(2)设置chart的样式:包括chart的样式、坐标轴的样式和图例的样式等 ;(3)为chart添加数据:先定义相应的Entry列表,并添加到DataSet中,然后再添加到ChartData对象中,最后再赋值给该Chart并刷新即可。 3、项目已上传至/WJKCharlie/MPAndroidChartTest。可前往下载代码自行查看。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。