build.gradle中应用MPAndroidChart包
implementation 'com.github.PhilJay:MPAndroidChart:v3.0.1'
MPChartHelper工具类
public class MPChartHelper {
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)
};
public static final int[] LINE_COLORS = {
Color.rgb(68,215,182), Color.rgb(255,65,48), Color.rgb(255,198,42), Color.rgb(74,119,252),
Color.rgb(255,0,255), Color.rgb(176,48,96), Color.rgb(69,139,0), Color.rgb(75,0,130),
Color.rgb(127,255,0), Color.rgb(142,56,142), Color.rgb(255,187,255), Color.rgb(237, 189, 189), Color.rgb(172, 217, 243)
};//绿色,紫色,黄色
public static final int[] LINE_FILL_COLORS = {
Color.rgb(222, 239, 228), Color.rgb(246, 234, 208), Color.rgb(235, 228, 248)
};
/**
* 单数据集。设置柱状图样式,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);
}
}
/**
* 设置正负值在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);
}
}
/**
* 设置双柱状图样式
*
* @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);
}
/**
* 设置三柱状图样式
*
* @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);
}
/**
* 单线单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, false, true);
}
/**
* 绘制线图,默认最多绘制三种颜色。所有线均依赖左侧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,
boolean isShowTL, boolean isScroll) {
lineChart.getDescription().setEnabled(false);//设置描述
// lineChart.setPinchZoom(true);//设置按比例放缩柱状图
lineChart.setScaleEnabled(false);//禁止缩放
// lineChart.setScaleXEnabled(true); //支持x轴缩放
// lineChart.setScaleYEnabled(false); //禁止y轴缩放
if (isScroll) {
//大于10时设置缩放
float ratio = 1f;
if (xAxisValue.size() > 10) {
ratio = (float) xAxisValue.size() / (float) 10;
lineChart.moveViewToX(0);
}
lineChart.zoom(0, 1f, 0, 0);
lineChart.zoom(ratio, 1f, 0, 0);
}
LineMarkerViews markerView = new LineMarkerViews(lineChart.getContext(), R.layout.custom_line_marker_view,lineChart,xAxisValue);
lineChart.setMarker(markerView);
//x坐标轴设置
IAxisValueFormatter xAxisFormatter = new StringAxisValueFormatter(xAxisValue);
XAxis xAxis = lineChart.getXAxis();
xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
xAxis.setDrawGridLines(false);
xAxis.setDrawAxisLine(false);
//设置x轴文字倾斜的角度
if (isScroll) {
xAxis.setLabelRotationAngle(-60);
} else {
xAxis.setLabelRotationAngle(0);
}
xAxis.setGranularity(1f);
xAxis.setLabelCount(xAxisValue.size());
xAxis.setTextColor(MyApp.context.getResources().getColor(R.color.text_color_3));
xAxis.setAxisLineColor(MyApp.context.getResources().getColor(R.color.paint_color6));
xAxis.setTextSize(12);
xAxis.setAxisLineWidth(1f);
xAxis.setValueFormatter(new IndexAxisValueFormatter(xAxisValue)/*xAxisFormatter*/);
//y轴设置
YAxis leftAxis = lineChart.getAxisLeft();
leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
leftAxis.setDrawGridLines(true);
leftAxis.setDrawAxisLine(false);
leftAxis.setGridLineWidth(1f);
leftAxis.setAxisLineWidth(1f);
leftAxis.setTextSize(12);
leftAxis.setGridColor(MyApp.context.getResources().getColor(R.color.paint_color6));
leftAxis.setAxisLineColor(MyApp.context.getResources().getColor(R.color.paint_color6));
leftAxis.setTextColor(MyApp.context.getResources().getColor(R.color.text_color_3));
if (showSetValues) {
leftAxis.setDrawLabels(false);//折线上显示值,则不显示坐标轴上的值
}
lineChart.getAxisRight().setEnabled(false);//不显示右边的y轴
//图例设置
Legend legend = lineChart.getLegend();
// legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
// legend.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
// legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
// legend.setDrawInside(false);
legend.setEnabled(false);//是否显示图例
// legend.setDirection(Legend.LegendDirection.LEFT_TO_RIGHT);
// legend.setForm(Legend.LegendForm.LINE);
// legend.setTextSize(12f);
//设置柱状图数据
setLinesChartData(lineChart, yXAxisValues, titles, showSetValues, lineColors);
lineChart.invalidate();
lineChart.setExtraOffsets(10, 0, 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<>();
if (entriesList.size() > 0 && titles.size() > 0) {
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);
}
set.setLineWidth(3f);//设置线的宽度
set.setMode(LineDataSet.Mode.CUBIC_BEZIER);//设置为曲线模式
//是否画折线点上的空心圆 false表示直接画成实心圆
set.setDrawCircleHole(false);
set.setCircleRadius(1);//设置圆的半径
set.enableDashedHighlightLine(10f, 10f, 0f);//点击后的高亮线的显示样式
set.setHighLightColor(Color.parseColor("#BCC0C4"));//设置点击交点后显示交高亮线的颜色
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);
}
}
/**
* 设置饼图样式
*
* @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();
}
/**
* 设置柱线组合图样式,柱图依赖左侧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;
}
}
ArrowTextView
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(TypedValue.COMPLEX_UNIT_PX, 5, getResources().getDisplayMetrics());
}
if (arrowWidth == 0) {
arrowWidth = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_PX, 20, getResources().getDisplayMetrics());
}
if (arrowHeight == 0) {
arrowHeight = TypedValue.applyDimension(TypedValue.COMPLEX_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);
}
}
LineMarkerViews
public class LineMarkerViews extends MarkerView {//继承MarkerVIew
private TextView tvContent;//自己定义的xmL
private LineChart lineChart;//图表控件
private List<String> xvalue;//X轴数据源
/**
* Constructor. Sets up the MarkerView with a custom layout resource.
*
* @param context
* @param layoutResource the layout resource to use for the MarkerView
*/
public LineMarkerViews(Context context, int layoutResource, LineChart lineChart, List<String> xvalue) {
super(context, layoutResource);
tvContent = (TextView) findViewById(R.id.tvContent);
this.lineChart = lineChart;
this.xvalue = xvalue;
}
@Override
public void refreshContent(Entry e, Highlight highlight) {
//下面这里是关键的
LineData lineData = lineChart.getLineData();//得到已经绘制成型的折线图的数据
int DataSetIndex = highlight.getDataSetIndex();//获取点击的是哪条折线上的交叉点,0就是第一条,以此类推
ILineDataSet set = lineData.getDataSetByIndex(DataSetIndex);
int index;
index = set.getEntryIndex(e);//根据点击的该条折线的点,获取当前Y轴数据对应的index值,
//根据index值,分别获取当前X轴上对应的两条折线的Y轴的值
Entry entry = set.getEntryForIndex(index);
// tvContent.setText("指标值:" + entry.getY() + "\n时间:" + xvalue.get(index)); // set the entry-value as the display text
tvContent.setText(StringUtils.double2String(e.getY(), 2));
super.refreshContent(e, highlight);
}
@Override
public MPPointF getOffset() {
return new MPPointF(-(getWidth() / 2), -getHeight());
}
}
MPChartMarkerView
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;
}
}
MyValueFormatter
public class MyValueFormatter implements IValueFormatter {
@Override
public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
return StringUtils.double2String(value, 2);
}
}
StringAxisValueFormatter
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
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);
}
}
ArrowTextView
<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>
custom_line_marker_view
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
>
<TextView
android:id="@+id/tvContent"
android:layout_width="@dimen/dp_40"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:background="@drawable/white_shape"
android:layout_marginTop="5dp"
android:layout_marginLeft="5dp"
android:gravity="center"
android:layout_marginRight="5dp"
android:text="0.56"
android:singleLine="false"
android:textSize="@dimen/sp_12"
android:textColor="#333333"
android:textAppearance="?android:attr/textAppearanceSmall" />
<!-- -->
</RelativeLayout>
custom_marker_view
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:orientation="vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<com.dingler.water.cloud.functionbag.drainersmanager.watermonitoring.analysis.view.zx.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="#686868"
android:maxLines="1"
android:ellipsize="end"
app:bg="#DEEFE4"
app:radius="5px"/>
</LinearLayout>
activity应用
//布局文件
<com.github.mikephil.charting.charts.LineChart
android:id="@+id/lineChart1"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_300"
android:visibility="gone" />
//fragment和activity中的应用
private void initDayData() {
if (dayData.size() > 0) {
//X轴数字
dayXAxisValues = new ArrayList<>();
List<DayBean.DataBean.DateCountListBean> dateCountList1 = dayData.get(0).getDateCountList();
for (int i = 0; i < dateCountList1.size(); i++) {
dayXAxisValues.add(dateCountList1.get(i).getDate());
}
//Y轴数字
dayYAxisValues = new ArrayList<>();
for (int i = 0; i < dayData.size(); ++i) {
List<Float> yAxisValues1 = new ArrayList<>();
for (PopupMoreBean moreBean : indexStringData) {
if (moreBean.getId() == dayData.get(i).getId() && moreBean.isSelect()) {
List<DayBean.DataBean.DateCountListBean> dateCountList = dayData.get(i).getDateCountList();
for (DayBean.DataBean.DateCountListBean bean : dateCountList) {
yAxisValues1.add((float) (bean.getAbnormalRate()));
}
}
}
dayYAxisValues.add(yAxisValues1);
}
//图例标志
dayTitles = new ArrayList<>();
for (int i = 0; i < indexStringData.size(); i++) {
dayTitles.add(indexStringData.get(i).getText());
}
MPChartHelper.setLinesChart(viewBinding.lineChart1, dayXAxisValues, dayYAxisValues, dayTitles, false, null, true, true);
}
}
网友评论