xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
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"/>
MyValueFormatter.java定义如下:
package com.charlie.mpandroidcharttest.common;
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 2016/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.charlie.mpandroidcharttest.common;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import java.util.List;
/**
* Created by Charlie on 2016/9/23.
* 对字符串类型的坐标轴标记进行格式化
*/
public class StringAxisValueFormatter implements IAxisValueFormatter {
//区域值
private List mStrs;
/**
* 对字符串类型的坐标轴标记进行格式化
* @param strs
*/
public StringAxisValueFormatter(List 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 2016/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 xAxisValue, List yAxisValue1, List 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 xAxisValue, List yAxisValue1, List 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 entries1 = new ArrayList<>();
ArrayList 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 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 xAxisValue, List yAxisValue1, List yAxisValue2, List 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 xAxisValue, List yAxisValue1, List yAxisValue2, List 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 first_entries = new ArrayList<>();
ArrayList second_entries = new ArrayList<>();
ArrayList 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 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、正负柱图:
先看效果图,如下: