MPAndroidChart 曲线图LineChart使用部分示例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_16064871/article/details/84501575

前段是使用LineChart画图,有不少总结,毕竟要满足客户各种需求。有个是曲线动态变化,有一个是查询后查看数据。

这个开源库的GitHub地址:

https://github.com/PhilJay/MPAndroidChart

1,直接看两个封装的代码

import android.content.Context;

import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.DefaultValueFormatter;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.gizwits.opensource.appkit.view.LineChartMarkView;

import java.text.DecimalFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;

/**
 * 动态参数变化
 */

public class DycLineChartManager {

    private LineChart lineChart;
    private YAxis leftAxis;
    private YAxis rightAxis;
    private XAxis xAxis;
    private LineData lineData;
    private LineDataSet lineDataSet;
    private SimpleDateFormat dfs = new SimpleDateFormat("HH:mm:ss");//设置日期格式  
    private List<String> timeList = new ArrayList<>(); //存储x轴的时间
    private int index = 0;
    private int indexX = 35;
    private List<Entry> entries = new ArrayList<>();
    private LineChartMarkView mv = null;
    protected int mDecimalDigits;
    protected DecimalFormat mFormat;

    //一条曲线
    public DynamicLineChartManager(LineChart mLineChart, String name, String unit, int color, int mDecimalDigits, int digits) {
        this.lineChart = mLineChart;
        this.mDecimalDigits = mDecimalDigits;
        leftAxis = lineChart.getAxisLeft();
        rightAxis = lineChart.getAxisRight();
        xAxis = lineChart.getXAxis();
        setup(digits);
        initLineChart(unit);
        initLineDataSet(name, color);
    }

    public void setup(int digits) {
        StringBuffer b = new StringBuffer();

        for (int i = 0; i < digits; ++i) {
            if (i == 0) {
                b.append(".");
            }

            b.append("0");
        }

        this.mFormat = new DecimalFormat("###,###,###,##0" + b.toString());
    }

    private long dateConvertMillionSec(String str) {
        long millionSeconds = 0;
        try {
            millionSeconds = new SimpleDateFormat("yyyyMMddHHmm").parse(str).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return millionSeconds;
    }

    /**
     * 初始化LineChar
     */
    private void initLineChart(final String unit) {

        lineChart.setDrawGridBackground(false);
        //显示边界
        lineChart.setDrawBorders(true);
        //折线图例 标签 设置
        Legend legend = lineChart.getLegend();
        legend.setForm(Legend.LegendForm.LINE);
        legend.setTextSize(11f);
        //显示位置
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        legend.setDrawInside(false);

        Long time = System.currentTimeMillis();
        String temp = "";
        SimpleDateFormat now = new SimpleDateFormat("yyyyMMddHHmm");
        String strNow = now.format(time);

        time = dateConvertMillionSec(strNow);

        timeList.add(dfs.format(time));
        for (int i = 0; i < 360; i++) {
            //增加下一个5分钟的刻度
            time = time + 1000 * 5;
            temp = dfs.format(time);
            timeList.add(temp);
        }


        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                String temp = "";
                int n = (int) value % timeList.size();
                //修复了数组越界的异常
                if (n > 0 && n < timeList.size()) {
                    String tradeDate = timeList.get(n);
                    temp = tradeDate.substring(tradeDate.length() - 2, tradeDate.length());
                    if (temp.equals("00")) {
                        temp = tradeDate.substring(0, tradeDate.length() - 3);
                    } else {
                        temp = "";
                    }
                }
                return temp;
            }
        });

        leftAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                String strTemp = mFormat.format(value) + " " + unit;
                return strTemp;
            }
        });

        //X轴设置显示位置在底部
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setGranularity(1f);

//        xAxis.setSpaceMax(1f);
        //保证Y轴从0开始,不然会上移一点
        leftAxis.setAxisMinimum(0f);
        rightAxis.setAxisMinimum(0f);

        //将右边那条线隐藏
        lineChart.getAxisRight().setEnabled(false); // 隐藏右边 的坐标轴
        lineChart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM); // 让x轴在下面
        lineChart.getXAxis().setGridColor(0x00ffffff);

        lineChart.getXAxis().setDrawAxisLine(false);
        lineChart.getAxisRight().setDrawAxisLine(false);
        lineChart.invalidate();
    }

    /**
     * 初始化折线(一条线)
     *
     * @param name
     * @param color
     */
    private void initLineDataSet(String name, int color) {
        for (int i = 0; i < timeList.size(); i++) {
            Entry entry = new Entry(i, 0);
            entries.add(entry);
        }

        lineDataSet = new LineDataSet(entries, name);
        lineDataSet.setLineWidth(1.5f);
        lineDataSet.setCircleRadius(1.5f);
        lineDataSet.setColor(color);
        lineDataSet.setCircleColor(color);
        lineDataSet.setFillColor(color);
        lineDataSet.setHighLightColor(color);
        setDescription("");
        lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
        //设置曲线填充
        lineDataSet.setDrawFilled(true);
        lineDataSet.setValueTextSize(10f);
        //设置线型模式,设置CUBIC_BEZIER 时候,当数据跟密集,y轴数据很稀疏时候。线型更新时候会凸起
        //所以换成LINEAR
        lineDataSet.setMode(LineDataSet.Mode.LINEAR);

        //添加一个空的 LineData
        lineData = new LineData(lineDataSet);

        //是否显示值
        lineData.setDrawValues(false);
        //设置显示数据的多少位 很难找到这个方法
        lineData.setValueFormatter(new DefaultValueFormatter(mDecimalDigits));
        lineChart.setData(lineData);
//        lineChart.setScaleX(1f);
        //显示数量
        xAxis.setLabelCount(360);
        //显示的时候是按照多大的比率缩放显示,1f表示不放大缩小
        lineChart.zoom(1f, 1f, 0, 0);
        //缩放时候,能最大的显示范围
        lineChart.setVisibleXRangeMaximum(36);
        lineChart.invalidate();
    }


    /**
     * 动态添加数据(一条折线图)
     *
     * @param number
     */
    public void addEntry(float number, int digits) {

        Entry entry = new Entry(index, number);
        entries.set(index, entry);
        lineDataSet.setValues(entries);

        lineData = new LineData(lineDataSet);
        //是否显示值
        lineData.setDrawValues(false);
        //设置显示数据的多少位 很难找到这个方法
        lineData.setValueFormatter(new DefaultValueFormatter(digits));
        lineChart.setData(lineData);
        index++;
        //通知数据已经改变
        lineData.notifyDataChanged();
        lineChart.notifyDataSetChanged();
        if (index > indexX) {
            indexX = indexX + 35;
            //移到某个位置
            lineChart.moveViewToX(index - 2);
        }
        if (mv != null) {
            mv.refreshContent(entry, null);
        }

        lineChart.invalidate();
    }


    /**
     * 设置Y轴值
     */
    public void setYAxis(float max, float min, int labelCount) {
        if (max < min) {
            return;
        }
        leftAxis.setAxisMaximum(max);
        leftAxis.setAxisMinimum(min);
        leftAxis.setLabelCount(labelCount, false);
        lineChart.invalidate();
    }

    /**
     * 设置 可以显示X Y 轴自定义值的 MarkerView
     */
    public void setMarkerView(Context context) {
        mv = new LineChartMarkView(context, xAxis.getValueFormatter(), timeList, mDecimalDigits);
        mv.setChartView(lineChart);
        lineChart.setMarker(mv);
        lineChart.invalidate();
    }

    /**
     * 设置描述信息
     *
     * @param str
     */
    public void setDescription(String str) {
        Description description = new Description();
        description.setText(str);
        description.setTextSize(14);
        lineChart.setDescription(description);
        lineChart.invalidate();
    }
}
import android.content.Context;

import com.custom.net.HistoryData;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.components.Description;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.DefaultValueFormatter;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.formatter.IValueFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.github.mikephil.charting.utils.ViewPortHandler;
import com.gizwits.opensource.appkit.view.LineChartMarkView;

import java.lang.annotation.Target;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;


public class LineChartManager {

    private LineChart lineChart;
    private YAxis leftAxis;
    private YAxis rightAxis;
    private XAxis xAxis;
    private LineData lineData;
    private LineDataSet lineDataSet;
    List<String> dataXList = new LinkedList<>();
    protected int mDecimalDigits;
    protected DecimalFormat mFormat;

    //一条曲线
    public ShowLineChartManager(LineChart mLineChart, String unit, int digits) {
        this.lineChart = mLineChart;
        leftAxis = lineChart.getAxisLeft();
        rightAxis = lineChart.getAxisRight();
        xAxis = lineChart.getXAxis();

        setup(digits);
        initLineChart(unit);
    }

    public void setup(int digits) {
        StringBuffer b = new StringBuffer();

        for (int i = 0; i < digits; ++i) {
            if (i == 0) {
                b.append(".");
            }

            b.append("0");
        }

        this.mFormat = new DecimalFormat("###,###,###,##0" + b.toString());
    }

    /**
     * 初始化LineChar
     */
    private void initLineChart(final String unit) {

        lineChart.setDrawGridBackground(false);
        //显示边界
        lineChart.setDrawBorders(true);
        //折线图例 标签 设置
        Legend legend = lineChart.getLegend();
        legend.setForm(Legend.LegendForm.LINE);
        legend.setTextSize(11f);
        //显示位置
        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        legend.setDrawInside(false);

        //设置图表距离上下左右的距离
        lineChart.setExtraOffsets(0, 0, 0, 10);

        //X轴设置显示位置在底部
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setGranularity(1f);
        xAxis.setGridLineWidth(2f);

        leftAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                String strTemp = mFormat.format(value) + " " + unit;
                return strTemp;
            }
        });

        //保证Y轴从0开始,不然会上移一点
        leftAxis.setAxisMinimum(0f);
        rightAxis.setAxisMinimum(0f);
        //将右边那条线隐藏
        lineChart.getAxisRight().setEnabled(false); // 隐藏右边 的坐标轴
        lineChart.getXAxis().setPosition(XAxis.XAxisPosition.BOTTOM); // 让x轴在下面
        lineChart.getXAxis().setGridColor(0x00ffffff);

        // 设置右边的label不可用
        rightAxis.setDrawLabels(false);
        // 设置右边的线不可用
        rightAxis.setDrawGridLines(false);
        // 设置右边的线不可用
        rightAxis.setDrawAxisLine(false);
    }

    /**
     * 初始化折线(一条线)
     */
    public void initLineDataSet(final List<Float> dataList, String name, int color, int digits) {

        float value = Collections.max(dataList);

        this.mDecimalDigits = digits;
        List<Entry> entries = new ArrayList<>();
        for (int i = 0; i < dataList.size(); i++) {
            /**
             * 在此可查看 Entry构造方法,可发现 可传入数值 Entry(float x, float y)
             * 也可传入Drawable, Entry(float x, float y, Drawable icon) 可在XY轴交点 设置Drawable图像展示
             */
            Entry entry = new Entry(i, dataList.get(i));
            entries.add(entry);
        }
        // 每一个LineDataSet代表一条线
        lineDataSet = new LineDataSet(entries, name);

        lineDataSet.setLineWidth(1.5f);
        lineDataSet.setCircleRadius(1.5f);
        lineDataSet.setColor(color);
        lineDataSet.setCircleColor(color);
        lineDataSet.setFillColor(color);
        lineDataSet.setHighLightColor(color);
        setDescription("");
        lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
        //设置曲线填充
        lineDataSet.setDrawFilled(true);
        lineDataSet.setValueTextSize(10f);
        lineDataSet.setMode(LineDataSet.Mode.LINEAR);

        //设置参数
        lineData = new LineData(lineDataSet);

        //设置显示数据的多少位 很难找到这个方法
        lineData.setValueFormatter(new DefaultValueFormatter(digits));


        //是否显示值
        lineData.setDrawValues(false);
        lineChart.setData(lineData);
        xAxis.setLabelCount(30);
        //显示的时候是按照多大的比率缩放显示,1f表示不放大缩小
        lineChart.zoom(1f, 1f, 0, 0);
        lineChart.setScaleMinima(1f,1f);
        lineChart.setVisibleXRangeMaximum(30);
        //移到某个位置
        lineChart.moveViewToX(lineData.getEntryCount());
        lineChart.invalidate();
    }


    /**
     * 设置Y轴值
     */
    public void setYAxis(float max, float min, int labelCount) {
        if (max < min) {
            return;
        }
        leftAxis.setAxisMaximum(max);
        leftAxis.setAxisMinimum(min);
        leftAxis.setLabelCount(labelCount, false);
        lineChart.invalidate();
    }

    /**
     * 设置X轴值
     */
    public void setXAxis(final List<HistoryData> dataList) {

        for (HistoryData data : dataList) {
            String tradeDate = data.getDatetime();
            if (tradeDate.length() >= 10) {
                String temp = tradeDate.substring(tradeDate.length() - 2, tradeDate.length());
                if (temp.equals("00")) {
                    tradeDate = tradeDate.substring(0, 4) + "年" +
                            tradeDate.substring(tradeDate.length() - 6, tradeDate.length() - 4) + "月" +
                            tradeDate.substring(tradeDate.length() - 4, tradeDate.length() - 2) + "日";
                } else {
                    tradeDate = tradeDate.substring(0, 4) + "年" +
                            tradeDate.substring(tradeDate.length() - 6, tradeDate.length() - 4) + "月" +
                            tradeDate.substring(tradeDate.length() - 4, tradeDate.length() - 2) + "日" +
                            temp.replaceFirst("^0*", "") + "时";
                }
                dataXList.add(tradeDate);
            }
        }

        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                String tradeDate = dataList.get((int) value).getDatetime();
                if (tradeDate.length() >= 10) {
                    String temp = tradeDate.substring(tradeDate.length() - 2, tradeDate.length());
                    if (temp.equals("00") || temp.equals("24")) {
                        tradeDate = tradeDate.substring(tradeDate.length() - 6, tradeDate.length() - 4) + "-" +
                                tradeDate.substring(tradeDate.length() - 4, tradeDate.length() - 2);

                    } else {
                        tradeDate = temp.replaceFirst("^0*", "");
                        switch (tradeDate) {
                            case "3":
                            case "6":
                            case "9":
                            case "12":
                            case "15":
                            case "18":
                            case "21":
                                break;
                            default:
                                tradeDate = "";
                                break;
                        }
                    }
                }
                return tradeDate;
            }
        });

        lineChart.invalidate();
    }

    /**
     * 设置 可以显示X Y 轴自定义值的 MarkerView
     */
    public void setMarkerView(Context context) {
        LineChartMarkView mv = new LineChartMarkView(context, xAxis.getValueFormatter(), dataXList, mDecimalDigits);
        mv.setChartView(lineChart);
        lineChart.setMarker(mv);
        lineChart.invalidate();
    }

    /**
     * 设置描述信息
     *
     * @param str
     */
    public void setDescription(String str) {
        Description description = new Description();
        description.setText(str);
        description.setTextSize(14);
        lineChart.setDescription(description);
        lineChart.invalidate();
    }
}

里面涉及到很多小技巧。

还有一个弹出来显示的数值。

package com.gizwits.opensource.appkit.view;

import android.annotation.SuppressLint;
import android.content.Context;
import android.text.TextUtils;
import android.widget.TextView;

import com.github.mikephil.charting.charts.Chart;
import com.github.mikephil.charting.charts.LineChart;
import com.github.mikephil.charting.components.MarkerView;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.LineData;
import com.github.mikephil.charting.data.LineDataSet;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.utils.MPPointF;
import com.gizwits.opensource.appkit.R;

import java.text.DecimalFormat;
import java.util.EventListener;
import java.util.LinkedList;
import java.util.List;

/**
 * Created by xhu_ww on 2018/6/1.
 * description:
 */
public class LineChartMarkView extends MarkerView {

    private TextView tvDate;
    private TextView tvValue0;
    private IAxisValueFormatter xAxisValueFormatter;
    List<String> dataXList = new LinkedList<>();
    protected DecimalFormat mFormat;
    protected int mDecimalDigits;

    public LineChartMarkView(Context context, IAxisValueFormatter xAxisValueFormatter, List<String> dataXList, int digits) {
        super(context, R.layout.layout_markview);
        this.xAxisValueFormatter = xAxisValueFormatter;
        this.dataXList = dataXList;
        this.mDecimalDigits = digits;
        setup(mDecimalDigits);
        tvDate = (TextView) findViewById(R.id.tv_date);
        tvValue0 = (TextView) findViewById(R.id.tv_value0);
    }

    public void setup(int digits) {
        this.mDecimalDigits = digits;
        StringBuffer b = new StringBuffer();

        for(int i = 0; i < digits; ++i) {
            if(i == 0) {
                b.append(".");
            }

            b.append("0");
        }

        this.mFormat = new DecimalFormat("###,###,###,##0" + b.toString());
    }

    @SuppressLint("SetTextI18n")
    @Override
    public void refreshContent(Entry e, Highlight highlight) {
        Chart chart = getChartView();
        if (chart instanceof LineChart) {
            LineData lineData = ((LineChart) chart).getLineData();
            //获取到图表中的所有曲线
            List<ILineDataSet> dataSetList = lineData.getDataSets();
            for (int i = 0; i < dataSetList.size(); i++) {
                LineDataSet dataSet = (LineDataSet) dataSetList.get(i);
                //获取到曲线的所有在Y轴的数据集合,根据当前X轴的位置 来获取对应的Y轴值
                float y = dataSet.getValues().get((int) e.getX()).getY();
                if (i == 0) {
                    tvValue0.setText(dataSet.getLabel() + ":" + mFormat.format(y));
                }
            }
//            String temp = xAxisValueFormatter.getFormattedValue(e.getX(), null);

            //获取全部刻度,包括不显示的刻度
            String temp = dataXList.get((int) e.getX());
            if (!TextUtils.isEmpty(temp)) {
                tvDate.setText(temp);

            }

        }
        super.refreshContent(e, highlight);
    }

    @Override
    public MPPointF getOffset() {
        return new MPPointF(-(getWidth() / 2), -getHeight());
    }
}

猜你喜欢

转载自blog.csdn.net/qq_16064871/article/details/84501575