MPAndroidChart折线图的使用

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 xAxisValue, List 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 yAxisValue, String title, Integer barColor) {

        ArrayList 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 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 xAxisValue, List 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 = 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 dataList, String title) {

        ArrayList values = new ArrayList();
        List colors = new ArrayList();

        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 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);
    }


    /**
     * 设置三柱状图样式
     *
     * @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);
    }


    /**
     * 单线单y轴图。
     *
     * @param lineChart
     * @param xAxisValue
     * @param yAxisValue
     * @param title
     * @param showSetValues 是否在折线上显示数据集的值。true为显示,此时y轴上的数值不可见,否则相反。
     */
    public static void setLineChart(LineChart lineChart, List xAxisValue, List yAxisValue, String title, boolean showSetValues) {
        List> entriesList = new ArrayList<>();
        entriesList.add(yAxisValue);

        List 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 xAxisValue, List> yXAxisValues, List 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> yXAxisValues, List titles, boolean showSetValues, int[] lineColors) {

        List> entriesList = new ArrayList<>();
        for (int i = 0; i < yXAxisValues.size(); ++i) {
            ArrayList 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 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 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 pieValues) {
        ArrayList 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 xAxisValues, List lineValues, List 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 lineValues, String lineTitle) {
        ArrayList 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 barValues, String barTitle) {

        ArrayList 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 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 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 mStrs;

    /**
     * 对字符串类型的坐标轴标记进行格式化
     * @param strs
     */
    public StringAxisValueFormatter(List 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

   
        
        
        
        
    

custom_line_marker_view



    
    


custom_marker_view



    

activity应用

//布局文件
 


//fragment和activity中的应用
  private void initDayData() {
      
        if (dayData.size() > 0) {
        //X轴数字
            dayXAxisValues = new ArrayList<>();
            List 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 yAxisValues1 = new ArrayList<>();
                for (PopupMoreBean moreBean : indexStringData) {
                    if (moreBean.getId() == dayData.get(i).getId() && moreBean.isSelect()) {
                    
                        List 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);
        }
    }

你可能感兴趣的:(MPAndroidChart折线图的使用)