第三方開源庫之 MPAndroidChart

目前版本 3.1.0
GitHub 地址:https://github.com/PhilJay/MPAndroidChart

簡介

  • 支持x,y軸縮放
  • 支持拖拽
  • 支持手指滑動
  • 支持高亮顯示
  • 支持保存圖表到文件中
  • 支持從文件(txt)中讀取數據
  • 預先定義顏色模板
  • 自動生成標註
  • 支持自定義x,y軸的顯示標籤
  • 支持x,y軸動畫
  • 支持x,y軸設置最大值和附加信息
  • 支持自定義字體,顏色,背景,手勢,虛線等

使用

  1. 在工程的 build.gradle 中添加如下:
allprojects {
    repositories {
        ...
        maven { url "https://www.jitpack.io" }
    }
}
  1. 在 app/build.gradle 添加如下依賴:
implementation 'com.github.PhilJay:MPAndroidChart:v3.1.0'

折線圖(LineChart)

管理類(LineChartManager.java)

public class LineChartManager {
    private LineChart lineChart;
    private YAxis leftAxis;
    private YAxis rightAxis;
    private XAxis xAxis;
    private LineData lineData;
    private LineDataSet lineDataSet;
    private List<ILineDataSet> lineDataSets = new ArrayList<>();
    private SimpleDateFormat df = new SimpleDateFormat("HH:mm:ss");//設置日期格式  
    private List<String> timeList = new ArrayList<>(); //存儲x軸的時間

    //一條曲線
    public LineChartManager(LineChart mLineChart, String name, int color) {
        this.lineChart = mLineChart;
        leftAxis = lineChart.getAxisLeft();
        rightAxis = lineChart.getAxisRight();
        xAxis = lineChart.getXAxis();
        initLineChart();
        initLineDataSet(name, color);
    }

    //多條曲線
    public LineChartManager(LineChart mLineChart, List<String> names, List<Integer> colors) {
        this.lineChart = mLineChart;
        leftAxis = lineChart.getAxisLeft();
        rightAxis = lineChart.getAxisRight();
        xAxis = lineChart.getXAxis();
        initLineChart();
        initLineDataSet(names, colors);
    }

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

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

        //X軸設置顯示位置在底部
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setGranularity(1f);
        xAxis.setLabelCount(10);


        //保證Y軸從0開始,不然會上移一點
        leftAxis.setAxisMinimum(0f);
        rightAxis.setAxisMinimum(0f);
    }

    /**
     * 初始化折線(一條線)
     *
     * @param name
     * @param color
     */
    private void initLineDataSet(String name, int color) {

        lineDataSet = new LineDataSet(null, name);
        lineDataSet.setLineWidth(1.5f);
        lineDataSet.setCircleRadius(1.5f);
        lineDataSet.setColor(color);
        lineDataSet.setCircleColor(color);
        lineDataSet.setHighLightColor(color);
        //設置曲線填充
        lineDataSet.setDrawFilled(false);
        lineDataSet.setDrawValues(false);
        lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
        lineDataSet.setValueTextSize(10f);
        lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
        //添加一個空的 LineData
        lineData = new LineData();
        lineChart.setData(lineData);
        lineChart.invalidate();

    }

    /**
     * 初始化折線(多條線)
     *
     * @param names
     * @param colors
     */
    private void initLineDataSet(List<String> names, List<Integer> colors) {

        for (int i = 0; i < names.size(); i++) {
            lineDataSet = new LineDataSet(null, names.get(i));
            lineDataSet.setColor(colors.get(i));
            lineDataSet.setLineWidth(1.5f);
            lineDataSet.setCircleRadius(1.5f);
            lineDataSet.setColor(colors.get(i));

            lineDataSet.setDrawFilled(false);
            lineDataSet.setDrawValues(false);
            lineDataSet.setCircleColor(colors.get(i));
            lineDataSet.setHighLightColor(colors.get(i));
            lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
            lineDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
            lineDataSet.setValueTextSize(10f);
            lineDataSets.add(lineDataSet);

        }
        //添加一個空的 LineData
        lineData = new LineData();
        lineChart.setData(lineData);
        lineChart.invalidate();
    }

    /**
     * 動態添加數據(一條折線圖)
     *
     * @param number
     */
    public void addEntry(int number) {

        //最開始的時候才添加 lineDataSet(一個lineDataSet 代表一條線)
        if (lineDataSet.getEntryCount() == 0) {
            lineData.addDataSet(lineDataSet);
        }
        lineChart.setData(lineData);
        //避免集合數據過多,及時清空(做這樣的處理,並不知道有沒有用,但還是這樣做了)
        if (timeList.size() > 11) {
            timeList.clear();
        }

        timeList.add(df.format(System.currentTimeMillis()));

        Entry entry = new Entry(lineDataSet.getEntryCount(), number);
        lineData.addEntry(entry, 0);
        //通知數據已經改變
        lineData.notifyDataChanged();
        lineChart.notifyDataSetChanged();
        //設置在曲線圖中顯示的最大數量
        lineChart.setVisibleXRangeMaximum(10);
        //移到某個位置
        lineChart.moveViewToX(lineData.getEntryCount() - 5);
    }

    /**
     * 動態添加數據(多條折線圖)
     *
     * @param numbers
     */
    public void addEntry(List<Float> numbers) {

        if (lineDataSets.get(0).getEntryCount() == 0) {
            lineData = new LineData(lineDataSets);
            lineChart.setData(lineData);
        }
        if (timeList.size() > 100) {
            timeList.clear();
        }
        timeList.add(df.format(System.currentTimeMillis()));
        for (int i = 0; i < numbers.size(); i++) {
            Entry entry = new Entry(lineDataSet.getEntryCount(), numbers.get(i));
            lineData.addEntry(entry, i);
            lineData.notifyDataChanged();
            lineChart.notifyDataSetChanged();
            lineChart.setVisibleXRangeMaximum(6);
            lineChart.moveViewToX(lineData.getEntryCount() - 5);
        }
    }

    /**
     * 設置Y軸值
     *
     * @param max
     * @param min
     * @param labelCount
     */
    public void setYAxis(float max, float min, int labelCount) {
        if (max < min) {
            return;
        }
        leftAxis.setAxisMaximum(max);
        leftAxis.setAxisMinimum(min);
        leftAxis.setLabelCount(labelCount, false);

        rightAxis.setAxisMaximum(max);
        rightAxis.setAxisMinimum(min);
        rightAxis.setLabelCount(labelCount, false);
        lineChart.invalidate();
    }

    /**
     * 設置高限制線
     *
     * @param high
     * @param name
     */
    public void setHightLimitLine(float high, String name, int color) {
        if (name == null) {
            name = "高限制線";
        }
        LimitLine hightLimit = new LimitLine(high, name);
        hightLimit.setLineWidth(4f);
        hightLimit.setTextSize(10f);
        hightLimit.setLineColor(color);
        hightLimit.setTextColor(color);
        leftAxis.addLimitLine(hightLimit);
        lineChart.invalidate();
    }

    /**
     * 設置低限制線
     *
     * @param low
     * @param name
     */
    public void setLowLimitLine(int low, String name) {
        if (name == null) {
            name = "低限制線";
        }
        LimitLine hightLimit = new LimitLine(low, name);
        hightLimit.setLineWidth(4f);
        hightLimit.setTextSize(10f);
        leftAxis.addLimitLine(hightLimit);
        lineChart.invalidate();
    }

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

一條曲線

  1. 效果圖
    01.png

  2. 佈局文件

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">

    <com.github.mikephil.charting.charts.LineChart
        android:id="@+id/line_chart"
        android:layout_width="match_parent"
        android:layout_height="320dp"/>

    <Button
        android:onClick="addEntry"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="隨機數"/>

</LinearLayout>
  1. 代碼
public class MainActivity extends AppCompatActivity {
    private LineChart mLineChart;

    private LineChartManager mChartManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        mChartManager = new LineChartManager(mLineChart,"sensors",Color.BLACK);
    }

    private void initView() {
        mLineChart = findViewById(R.id.line_chart);
    }

    public void addEntry(View view) {
        mChartManager.addEntry((int)(Math.random() * 100));
    }
}

餅圖

  1. 效果圖
    haha.png

  2. 佈局文件

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">

    <com.github.mikephil.charting.charts.PieChart
        android:id="@+id/pie_chart"
        android:layout_width="300dp"
        android:layout_height="300dp"/>

</LinearLayout>
  1. 代碼
public class MainActivity extends AppCompatActivity {
    private PieChart mPieChart;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initPieChart(mPieChart);
    }

    private void initPieChart(PieChart pieChart) {
        List<PieEntry> strings = new ArrayList<>();
        strings.add(new PieEntry(30f,"男生"));
        strings.add(new PieEntry(70f,"女生"));
        PieDataSet dataSet = new PieDataSet(strings,"");

        ArrayList<Integer> colors = new ArrayList<Integer>();
        colors.add(Color.RED);
        colors.add(Color.BLUE);
        dataSet.setColors(colors);

        PieData pieData = new PieData(dataSet);
        pieData.setDrawValues(true);
        pieData.setValueFormatter(new PercentFormatter(pieChart));
        pieData.setValueTextSize(12f);
        pieData.setValueTextColor(Color.WHITE);

        Description description = new Description();
        description.setText("");
        pieChart.setDescription(description);
        pieChart.setHoleRadius(0f);
        pieChart.setTransparentCircleRadius(0f);
        pieChart.setUsePercentValues(true);

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

    private void initView() {
        mPieChart = findViewById(R.id.pie_chart);
    }
}

柱狀圖

  1. 效果圖
    33.png

  2. 佈局文件

<?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"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">

    <com.github.mikephil.charting.charts.BarChart
        android:id="@+id/bar_chart"
        android:layout_width="match_parent"
        android:layout_height="300dp"/>

</LinearLayout>
  1. 代碼
public class MainActivity extends AppCompatActivity {
    private BarChart mBarChart;
    private List<BarEntry> mBarEntries;
    private BarData mBarData;
    private BarDataSet mBarDataSet;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initBarEntries();
        initBarData();
    }

    private void initView() {
        mBarChart = findViewById(R.id.bar_chart);
        mBarChart.setNoDataText("正在初始化...");
    }

    private void initBarEntries() {
        BarEntry barEntry1 = new BarEntry(0f, 30f);
        BarEntry barEntry2 = new BarEntry(1f, 40f);
        BarEntry barEntry3 = new BarEntry(2f, 50f);
        BarEntry barEntry4 = new BarEntry(3f, 60f);
        BarEntry barEntry5 = new BarEntry(4f, 70f);

        mBarEntries = new ArrayList<>();
        mBarEntries.add(barEntry1);
        mBarEntries.add(barEntry2);
        mBarEntries.add(barEntry3);
        mBarEntries.add(barEntry4);
        mBarEntries.add(barEntry5);
    }

    private void initBarData() {
        mBarDataSet = new BarDataSet(mBarEntries,"sleep");
        mBarData = new BarData(mBarDataSet);

        // mBarDataSet.setColors(colors); 給柱狀圖設置顏色

        initX(mBarChart);
        initY(mBarChart);

        Description desc = new Description();
        desc.setText("");
        mBarChart.setDescription(desc);
        mBarChart.setData(mBarData);
        mBarChart.invalidate();
    }

    private void initX(BarChart barChart) {
        final String[] weeks = {"週一","週二","週三","週四","週五"};

        XAxis xAxis = barChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setValueFormatter(new ValueFormatter() {
            @Override
            public String getFormattedValue(float value) {
                return weeks[(int)value];
            }
        });
        barChart.getLegend().setEnabled(false);
        xAxis.setLabelCount(weeks.length,false);
    }

    private void initY(BarChart barChart) {
        barChart.getAxisLeft().setDrawZeroLine(true);
        //去掉左側Y軸刻度
        barChart.getAxisLeft().setDrawLabels(false);
        //去掉左側Y軸
        barChart.getAxisLeft().setDrawAxisLine(false);
        //去掉中間豎線
        barChart.getXAxis().setDrawGridLines(false);
        //去掉中間橫線
        barChart.getAxisLeft().setDrawGridLines(false);
    }


}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章