1. 程式人生 > >MPAndroidChart3.0使用詳解(二)----柱狀圖、折線圖、組合圖的使用

MPAndroidChart3.0使用詳解(二)----柱狀圖、折線圖、組合圖的使用

上篇主要講到了MPAndroidChart這個開源庫的一些基本特性和基礎設定,現在來講下我們經常要用到的柱狀圖(直方圖)、折線圖和組合圖的使用。

柱狀圖

再講之前,先看效果圖。
這裡寫圖片描述
第一個是單個柱狀圖,第二個是組合(group)的柱狀圖
使用
1、首先先建立BarChart物件,並初始化,進行些基礎設定
2、為BarChart新增物件,利用BarEntry新增x軸,y軸的資料
3、初始化BarDataSet物件,為BarDataSet新增BarEntry物件
4、初始化BarData物件,為BarData新增BarDataSet
5、為BarChart新增BarData,即BarChart.setData(barData)
這樣就完成了柱狀圖的繪製。
一些BarChart屬性的設定

setDrawValueAboveBar(boolean enabled):// 如果設定為true,在條形圖上方顯示值。如果為false,會顯示在頂部下方。
setDrawBarShadow(boolean enabled):// 是否顯示陰影。啟動它會降低約40%的效能
setDrawValuesForWholeStack(boolean enabled):// 如果設定為true,堆疊條形的所有值會分別繪製,而不僅僅是他們所有的頂部總和。
setDrawHighlightArrow(boolean enabled):// 是否強調繪製箭頭

這裡已經封裝好了一個BarChartManager,使用的時候只用新增資料即可。程式碼如下:

import android.graphics.Color;

import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.BarChart;
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.BarData; import com.github.mikephil.charting.data.BarDataSet; import com.github.mikephil.charting.data.BarEntry; import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; import java.util.ArrayList; import java.util.List; /** * Descriptions:柱狀圖管理類 */ public class BarChartManager { private BarChart mBarChart; private YAxis leftAxis; private YAxis rightAxis; private XAxis xAxis; //顏色集合 List<Integer> colors = new ArrayList<>(); public BarChartManager(BarChart barChart) { this.mBarChart = barChart; leftAxis = mBarChart.getAxisLeft(); rightAxis = mBarChart.getAxisRight(); xAxis = mBarChart.getXAxis(); colors.add(Color.GREEN); colors.add(Color.BLUE); colors.add(Color.RED); colors.add(Color.CYAN); initBarChart(); } /** * 初始化LineChart */ private void initBarChart() { //背景顏色 mBarChart.setBackgroundColor(Color.WHITE); //網格 mBarChart.setDrawGridBackground(false); //背景陰影 mBarChart.setDrawBarShadow(false); mBarChart.setHighlightFullBarEnabled(false); //顯示邊界 mBarChart.setDrawBorders(false); //設定動畫效果 mBarChart.animateY(1000, Easing.EasingOption.Linear); mBarChart.animateX(1000, Easing.EasingOption.Linear); //圖表的描述 mBarChart.getDescription().setText(""); //折線圖例 標籤 設定 Legend legend = mBarChart.getLegend(); legend.setForm(Legend.LegendForm.SQUARE);//圖示 標籤的形狀。 正方形 legend.setTextSize(11f); //顯示位置 legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM); legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT); legend.setOrientation(Legend.LegendOrientation.HORIZONTAL); legend.setDrawInside(false); //XY軸的設定 //X軸設定顯示位置在底部 xAxis.setPosition(XAxis.XAxisPosition.BOTTOM); xAxis.setGranularity(1f);//設定最小的區間,避免標籤的迅速增多 xAxis.setDrawGridLines(false);//設定豎狀的線是否顯示 xAxis.setCenterAxisLabels(true);//設定標籤居中 // xAxis.setSpaceMax(10); // xAxis.setValueFormatter(); leftAxis.setDrawGridLines(true);//設定橫狀的線是否顯示 leftAxis.enableGridDashedLine(6f, 3f, 0);//虛線 leftAxis.setAxisLineWidth(1f); leftAxis.setEnabled(true); leftAxis.setGridColor(0xacb3e5fc); // leftAxis.setTextColor(0xb3e5fc);//設定左邊Y軸文字的顏色 // leftAxis.setAxisLineColor(0xb3e5fc);//設定左邊Y軸的顏色 // rightAxis.setDrawGridLines(false);//設定橫狀的線是否顯示 rightAxis.setEnabled(false);//隱藏右邊軸和數字 //保證Y軸從0開始,不然會上移一點 leftAxis.setAxisMinimum(0f); rightAxis.setAxisMinimum(0f); mBarChart.setDoubleTapToZoomEnabled(false); // 設定為false以禁止通過在其上雙擊縮放圖表。 // mBarChart.setBorderWidth(15);//設定邊界寬度 } /** * 展示柱狀圖(一條) * * @param xAxisValues * @param yAxisValues * @param label * @param color */ public void showBarChart(List<Float> xAxisValues, List<Float> yAxisValues, String label, int color) { ArrayList<BarEntry> entries = new ArrayList<>(); for (int i = 0; i < xAxisValues.size(); i++) { entries.add(new BarEntry(xAxisValues.get(i), yAxisValues.get(i))); } // 每一個BarDataSet代表一類柱狀圖 BarDataSet barDataSet = new BarDataSet(entries, label); barDataSet.setColor(color); barDataSet.setValueTextSize(9f); barDataSet.setFormLineWidth(1f); barDataSet.setFormSize(15.f); ArrayList<IBarDataSet> dataSets = new ArrayList<>(); dataSets.add(barDataSet); BarData data = new BarData(dataSets); //設定X軸的刻度數 xAxis.setLabelCount(xAxisValues.size()-1 , false); mBarChart.setData(data); } /** * 展示柱狀圖(多條) * * @param xAxisValues * @param yAxisValues * @param labels * @param colours */ public void showBarChart(List<Float> xAxisValues, List<List<Float>> yAxisValues, List<String> labels, List<Integer> colours) { BarData data = new BarData(); // xAxis.setValueFormatter(new StringAxisValueFormatter(xAxisValues)); for (int i = 0; i < yAxisValues.size(); i++) { ArrayList<BarEntry> entries = new ArrayList<>(); for (int j = 0; j < yAxisValues.get(i).size(); j++) { entries.add(new BarEntry(xAxisValues.get(i), yAxisValues.get(i).get(j))); } BarDataSet barDataSet = new BarDataSet(entries, labels.get(i)); barDataSet.setColor(colours.get(i)); barDataSet.setValueTextColor(colours.get(i)); barDataSet.setValueTextSize(10f); barDataSet.setAxisDependency(YAxis.AxisDependency.RIGHT); data.addDataSet(barDataSet); } int amount = yAxisValues.size(); float groupSpace = 0.12f; //柱狀圖組之間的間距 float barSpace = (float) ((1 - 0.12) / amount / 10); // x4 DataSet float barWidth = (float) ((1 - 0.12) / amount / 10 * 9); // x4 DataSet // (0.2 + 0.02) * 4 + 0.12 = 1.00 -> 組成1個"group"的寬度 xAxis.setLabelCount(xAxisValues.size() - 1, false); data.setBarWidth(barWidth); data.groupBars(0, groupSpace, barSpace); mBarChart.setData(data); } protected void showBarChart(List<String> xValues, List<List<Float>> yValuesList,List<String> labels){ mBarChart.getXAxis().setValueFormatter(new StringAxisValueFormatter(xValues)); BarData data = new BarData(); for (int i = 0; i < yValuesList.size(); i++) { ArrayList<BarEntry> entries = new ArrayList<>(); for (int j = 0; j < yValuesList.get(i).size(); j++) { entries.add(new BarEntry(i, yValuesList.get(i).get(j))); } // y軸的資料集合 BarDataSet barDataSet = new BarDataSet(entries, labels.get(i)); barDataSet.setColor(colors.get(i)); barDataSet.setValueTextColor(colors.get(i)); barDataSet.setValueTextSize(10f); data.addDataSet(barDataSet); } int amount = yValuesList.size(); float groupSpace = 0.12f; //柱狀圖組之間的間距 float barSpace = (float) ((1 - 0.12) / amount / 10); // x4 DataSet float barWidth = (float) ((1 - 0.12) / amount / 10 * 9); // x4 DataSet // (0.2 + 0.02) * 4 + 0.12 = 1.00 -> interval per "group" mBarChart.getXAxis().setLabelCount(xValues.size()-1, false); data.setBarWidth(barWidth); xAxis.setAxisMaximum(xValues.size()); xAxis.setAxisMinimum(0); data.groupBars(0, groupSpace, barSpace); mBarChart.setData(data); } protected BarData getBarData(List<String> xValues, List<List<Float>> yValuesList) { mBarChart.getXAxis().setValueFormatter(new StringAxisValueFormatter(xValues)); BarData data = new BarData(); for (int i = 0; i < yValuesList.size(); i++) { ArrayList<BarEntry> entries = new ArrayList<>(); for (int j = 0; j < yValuesList.get(i).size(); j++) { entries.add(new BarEntry(i, yValuesList.get(i).get(j))); } // y軸的資料集合 BarDataSet barDataSet = new BarDataSet(entries, xValues.get(i)); barDataSet.setColor(colors.get(i)); barDataSet.setValueTextColor(colors.get(i)); barDataSet.setValueTextSize(10f); data.addDataSet(barDataSet); } int amount = yValuesList.size(); float groupSpace = 0.12f; //柱狀圖組之間的間距 float barSpace = (float) ((1 - 0.12) / amount / 10); // x4 DataSet float barWidth = (float) ((1 - 0.12) / amount / 10 * 9); // x4 DataSet // (0.2 + 0.02) * 4 + 0.08 = 1.00 -> interval per "group" mBarChart.getXAxis().setLabelCount(xValues.size()-1, false); data.setBarWidth(barWidth); data.groupBars(0, groupSpace, barSpace); return data; } /** * 設定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); mBarChart.invalidate(); } /** * 設定X軸的值 * * @param max * @param min * @param labelCount */ public void setXAxis(float max, float min, int labelCount) { xAxis.setAxisMaximum(max); xAxis.setAxisMinimum(min); xAxis.setLabelCount(labelCount, false); mBarChart.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); mBarChart.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); mBarChart.invalidate(); } /** * 設定描述資訊 * * @param str */ public void setDescription(String str) { Description description = new Description(); description.setText(str); mBarChart.setDescription(description); mBarChart.invalidate(); } }

自定義的X軸資料轉換類

import com.github.mikephil.charting.components.AxisBase;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;

import java.util.List;

/*
 * Description: x軸資料轉換類
 */

public class StringAxisValueFormatter implements IAxisValueFormatter {

    private List<String> xValues;

    public StringAxisValueFormatter(List<String> xValues) {
        this.xValues = xValues;
    }

    @Override
    public String getFormattedValue(float v, AxisBase axisBase) {
        try{
            if (v < 0 || v > (xValues.size() - 1)){//使得兩側柱子完全顯示
                return "";
            }
            return xValues.get((int)v);
        }catch (Exception e){
            return "";
        }
    }
}

Activity使用的時候:

 private void testBarChart() {
        BarChartManager barChartManager1 = new BarChartManager(barChart1);
        BarChartManager barChartManager2 = new BarChartManager(barChart2);

        //設定x軸的資料
        ArrayList<String> xValues0 = new ArrayList<>();
        xValues0.add("早晨");
        xValues0.add("上午");
        xValues0.add("中午");
        xValues0.add("下午");
        xValues0.add("晚上");

        //設定x軸的資料
        ArrayList<Float> xValues = new ArrayList<>();
        for (int i = 1; i < 6; i++) {
            xValues.add((float) i);
        }

        //設定y軸的資料()
        List<List<Float>> yValues = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            List<Float> yValue = new ArrayList<>();
            for (int j = 0; j < 5; j++) {
                yValue.add((float) (Math.random() * 8)+2);
            }
            yValues.add(yValue);
        }

        //顏色集合
        List<Integer> colors = new ArrayList<>();
        colors.add(Color.GREEN);
        colors.add(Color.BLUE);
        colors.add(Color.RED);
        colors.add(Color.CYAN);

        //線的名字集合
        List<String> names = new ArrayList<>();
        names.add("柱狀一");
        names.add("柱狀二");
        names.add("柱狀三");
        names.add("柱狀四");

        //建立多條柱狀的圖表
        barChartManager1.showBarChart(xValues, yValues.get(0), names.get(1), colors.get(3));
        barChartManager2.showBarChart(xValues0, yValues,names);
    }

折線圖

效果圖如下:
這裡寫圖片描述

使用
1、初始化LineChart物件,設定基礎屬性
2、初始化Entry物件,新增x軸和y軸資料
3、初始化LineDataSet物件,為其新增Entry
4、初始化LineData物件,為其新增LineDataSet物件
5、設定資料,顯示圖表LineChart.setData(lineData)

一樣的,這裡也封裝了一個折線圖管理類LineChartManager,程式碼如下:

import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.LineChart;
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.interfaces.datasets.ILineDataSet;

import java.util.ArrayList;
import java.util.List;

/**
 * Descriptions: 折線圖管理類
 */

public class LineChartManager {
    private LineChart lineChart;
    private YAxis leftAxis;   //左邊Y軸
    private YAxis rightAxis;  //右邊Y軸
    private XAxis xAxis;      //X軸

    public LineChartManager(LineChart mLineChart) {
        this.lineChart = mLineChart;
        leftAxis = lineChart.getAxisLeft();
        rightAxis = lineChart.getAxisRight();
        xAxis = lineChart.getXAxis();
        initLineChart();
    }

    /**
     * 初始化LineChart
     */
    private void initLineChart() {
        lineChart.setDrawGridBackground(false);

        //顯示邊界
        lineChart.setDrawBorders(false);

        //設定動畫效果
        lineChart.animateY(1000, Easing.EasingOption.Linear);
        lineChart.animateX(1000, Easing.EasingOption.Linear);

        //折線圖例 標籤 設定
        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);

        //XY軸的設定
        //X軸設定顯示位置在底部
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setAxisMinimum(0f);
        xAxis.setGranularity(1f);

        //保證Y軸從0開始,不然會上移一點
        leftAxis.setAxisMinimum(0f);
        rightAxis.setAxisMinimum(0f);
        rightAxis.setEnabled(false);
//        xAxis.setDrawGridLines(false);//不繪製x軸網線
//        leftAxis.setDrawGridLines(false);//不繪製Y周網線
    }

    /**
     * 初始化曲線 每一個LineDataSet代表一條線
     *
     * @param lineDataSet
     * @param color
     * @param mode        折線圖是否填充
     */
    private void initLineDataSet(LineDataSet lineDataSet, int color, boolean mode) {
        lineDataSet.setColor(color);
        lineDataSet.setCircleColor(color);
        lineDataSet.setLineWidth(1f);
        lineDataSet.setCircleRadius(3f);
        //設定曲線值的圓點是實心還是空心
        lineDataSet.setDrawCircleHole(true);
        lineDataSet.setValueTextSize(9f);
        //設定折線圖填充
        lineDataSet.setDrawFilled(mode);//填充曲線下方的區域
        lineDataSet.setFormLineWidth(1f);
        lineDataSet.setFormSize(15.f);
        //線模式為圓滑曲線(預設折線)
        lineDataSet.setMode(LineDataSet.Mode.LINEAR);
    }

    /**
     * 展示折線圖(一條)
     *
     * @param xAxisValues
     * @param yAxisValues
     * @param label
     * @param color
     */
    public void showLineChart(List<Float> xAxisValues, List<Float> yAxisValues, String label, int color) {
        ArrayList<Entry> entries = new ArrayList<>();
        for (int i = 0; i < xAxisValues.size(); i++) {
            entries.add(new Entry(xAxisValues.get(i), yAxisValues.get(i)));
        }
        // 每一個LineDataSet代表一條線
        LineDataSet lineDataSet = new LineDataSet(entries, label);
        //線模式為圓滑曲線(預設折線)
        lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
        //設定圓心半徑
        lineDataSet.setCircleRadius(3f);
        //設定曲線值的圓點是實心還是空心
        lineDataSet.setDrawCircleHole(false);
        initLineDataSet(lineDataSet, color, false);

        ArrayList<ILineDataSet> dataSets = new ArrayList<>();
        dataSets.add(lineDataSet);
        LineData data = new LineData(dataSets);
        //設定X軸的刻度數
        xAxis.setLabelCount(xAxisValues.size());

        lineChart.setData(data);
    }

    public void showLineChart(List<String> xValues,List<Float> yValues,int color){
        ArrayList<Entry> entries = new ArrayList<>();
        xAxis.setValueFormatter(new StringAxisValueFormatter(xValues));
        for (int i = 0; i < xValues.size(); i++) {
            entries.add(new Entry( i, yValues.get(i)));
        }
        // 每一個LineDataSet代表一條線
        LineDataSet lineDataSet = new LineDataSet(entries, "折線test");
        initLineDataSet(lineDataSet, color, false);

        ArrayList<ILineDataSet> dataSets = new ArrayList<>();
        dataSets.add(lineDataSet);
        LineData data = new LineData(dataSets);
        //設定X軸的刻度數
        xAxis.setLabelCount(xValues.size());

        lineChart.setData(data);
    }

    /**
     * 展示線性圖(多條)
     *
     * @param xAxisValues
     * @param yAxisValues 多條曲線Y軸資料集合的集合
     * @param labels
     * @param colors
     */
    public void showLineChart(List<Float> xAxisValues, List<List<Float>> yAxisValues, List<String> labels, List<Integer> colors) {
        ArrayList<ILineDataSet> dataSets = new ArrayList<>();
        for (int i = 0; i < yAxisValues.size(); i++) {
            ArrayList<Entry> entries = new ArrayList<>();
            for (int j = 0; j < yAxisValues.get(i).size(); j++) {
//                if (j >= xAxisValues.size()) {
//                    j = xAxisValues.size() - 1;
//                }
                entries.add(new Entry(xAxisValues.get(j), yAxisValues.get(i).get(j)));
            }
            LineDataSet lineDataSet = new LineDataSet(entries, labels.get(i));

            initLineDataSet(lineDataSet, colors.get(i), false);
            dataSets.add(lineDataSet);
        }
        LineData data = new LineData(dataSets);
        xAxis.setLabelCount(xAxisValues.size(), true);
        lineChart.setData(data);
    }

    /**
     * 設定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();
    }

    /**
     * 設定X軸的值
     *
     * @param max
     * @param min
     * @param labelCount
     */
    public void setXAxis(float max, float min, int labelCount) {
        xAxis.setAxisMaximum(max);
        xAxis.setAxisMinimum(min);
        xAxis.setLabelCount(labelCount, true);

        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(2f);
        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();
    }
}

x軸資料轉換類程式碼就不貼了,柱狀圖上面有。
Activity中使用

/**
     * 測試折線圖
     */
    private void testLineChart() {
        LineChartManager lineChartManager1 = new LineChartManager(lineChart1);
        LineChartManager lineChartManager2 = new LineChartManager(lineChart2);

        //設定x軸的資料
        ArrayList<Float> xValues = new ArrayList<>();
        for (int i = 0; i < 10; i++) {//10組資料
            xValues.add((float) i);
        }

        //設定y軸的資料()
        List<List<Float>> yValues = new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            List<Float> yValue = new ArrayList<>();
            for (int j = 0; j < 10; j++) {
                yValue.add((float) (Math.random() * 80));
            }
            yValues.add(yValue);
        }

        //顏色集合
        List<Integer> colors = new ArrayList<>();
        colors.add(Color.GREEN);
        colors.add(Color.BLUE);
        colors.add(Color.RED);
        colors.add(Color.CYAN);

        //線的名字集合
        List<String> names = new ArrayList<>();
        names.add("折線一");
        names.add("折線二");
        names.add("折線三");
        names.add("折線四");

        //建立單條折線的圖表
        lineChartManager1.showLineChart(xValues, yValues.get(0), names.get(0), colors.get(0));
        lineChartManager1.setYAxis(100, 0, 11);
        lineChartManager1.setDescription("溫度");
        // lineChartManager1.setXAxis(10,0,xValues.size());
        lineChartManager1.setHightLimitLine(70,"高溫報警",Color.RED);

        //建立多條折線的圖表
       // lineChartManager2.showLineChart(xValues, yValues, names, colors);
       // lineChartManager2.setYAxis(100, 0, 11);
        lineChartManager2.showLineChart(xValues, yValues, names, colors);
        lineChartManager2.setYAxis(100, 0, 11);
        lineChartManager2.setDescription("溫度");
    }

組合圖

組合圖CombinedChart。這裡主要是折線圖和柱狀圖的組合形式
效果圖如下:
這裡寫圖片描述

xml檔案

 <com.github.mikephil.charting.charts.CombinedChart
            android:id="@+id/combine_chart2"
            android:layout_width="match_parent"
            android:layout_height="250dp"/>

這裡也封裝了一個CombinedChart工具類,CombinedChartManager程式碼如下:

public class CombinedChartManager {

    private CombinedChart mCombinedChart;
    private YAxis leftAxis;
    private YAxis rightAxis;
    private XAxis xAxis;

    public CombinedChartManager(CombinedChart combinedChart) {
        this.mCombinedChart = combinedChart;
        leftAxis = mCombinedChart.getAxisLeft();
        rightAxis = mCombinedChart.getAxisRight();
        xAxis = mCombinedChart.getXAxis();
    }

    /**
     * 初始化Chart
     */
    private void initChart() {
        //不顯示描述內容
        mCombinedChart.getDescription().setEnabled(false);

        mCombinedChart.setDrawOrder(new CombinedChart.DrawOrder[]{
                CombinedChart.DrawOrder.BAR,
                CombinedChart.DrawOrder.LINE
        });

        mCombinedChart.setBackgroundColor(Color.WHITE);
        mCombinedChart.setDrawGridBackground(false);
        mCombinedChart.setDrawBarShadow(false);
        mCombinedChart.setHighlightFullBarEnabled(false);
        //顯示邊界
        mCombinedChart.setDrawBorders(true);
        //圖例說明
        Legend legend = mCombinedChart.getLegend();
        legend.setWordWrapEnabled(true);

        legend.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        legend.setHorizontalAlignment(Legend.LegendHorizontalAlignment.CENTER);
        legend.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        legend.setDrawInside(false);
        //Y軸設定
        rightAxis.setDrawGridLines(false);
        rightAxis.setAxisMinimum(0f);

        leftAxis.setDrawGridLines(false);
        leftAxis.setAxisMinimum(0f);

        mCombinedChart.animateX(2000); // 立即執行的動畫,x軸
    }

    /**
     * 設定X軸座標值
     *
     * @param xAxisValues x軸座標集合
     */
    public void setXAxis(final List<String> xAxisValues) {

        //設定X軸在底部
        XAxis xAxis = mCombinedChart.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.setGranularity(1f);

        xAxis.setLabelCount(xAxisValues.size() - 1,false);
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
            public String getFormattedValue(float value, AxisBase axis) {
                return xAxisValues.get((int) value % xAxisValues.size());
            }
        });
        mCombinedChart.invalidate();
    }

    /**
     * 得到折線圖(一條)
     *
     * @param lineChartY 折線Y軸值
     * @param lineName   折線圖名字
     * @param lineColor  折線顏色
     * @return
     */
    private LineData getLineData(List<Float> lineChartY, String lineName, int lineColor) {
        LineData lineData = new LineData();

        ArrayList<Entry> yValue = new ArrayList<>();
        for (int i = 0; i < lineChartY.size(); i++) {
            yValue.add(new Entry(i, lineChartY.get(i)));
        }
        LineDataSet dataSet = new LineDataSet(yValue, lineName);

        dataSet.setColor(lineColor);
        dataSet.setCircleColor(lineColor);
        dataSet.setValueTextColor(lineColor);

        dataSet.setCircleSize(1);
        //顯示值
        dataSet.setDrawValues(true);
        dataSet.setValueTextSize(10f);
        dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
        dataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
        lineData.addDataSet(dataSet);
        return lineData;
    }

    /**
     * 得到折線圖(多條)
     *
     * @param lineChartYs 折線Y軸值
     * @param lineNames   折線圖名字
     * @param lineColors  折線顏色
     * @return
     */
    private LineData getLineData(List<List<Float>> lineChartYs, List<String> lineNames, List<Integer> lineColors) {
        LineData lineData = new LineData();

        for (int i = 0; i < lineChartYs.size(); i++) {
            ArrayList<Entry> yValues = new ArrayList<>();
            for (int j = 0; j < lineChartYs.get(i).size(); j++) {
                yValues.add(new Entry(j, lineChartYs.get(i).get(j)));
            }
            LineDataSet dataSet = new LineDataSet(yValues, lineNames.get(i));
            dataSet.setColor(lineColors.get(i));
            dataSet.setCircleColor(lineColors.get(i));
            dataSet.setValueTextColor(lineColors.get(i));

            dataSet.setCircleSize(1);
            dataSet.setDrawValues(true);
            dataSet.setValueTextSize(10f);
            dataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
            dataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
            lineData.addDataSet(dataSet);
        }
        return lineData;
    }

    /**
     * 得到柱狀圖
     *
     * @param barChartY Y軸值
     * @param barName   柱狀圖名字
     * @param barColor  柱狀圖顏色
     * @return
     */

    private BarData getBarData(List<Float> barChartY, String barName, int barColor) {
        BarData barData = new BarData();
        ArrayList<BarEntry> yValues = new ArrayList<>();
        for (int i = 0; i < barChartY.size(); i++) {
            yValues.add(new BarEntry(i, barChartY.get(i)));
        }

        BarDataSet barDataSet = new BarDataSet(yValues, barName);
        barDataSet.setColor(barColor);
        barDataSet.setValueTextSize(10f);
        barDataSet.setValueTextColor(barColor);
        barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
        barData.addDataSet(barDataSet);

        //以下是為了解決 柱狀圖 左右兩邊只顯示了一半的問題 根據實際情況 而定
        xAxis.setAxisMinimum(-0.5f);
        xAxis.setAxisMaximum((float) (barChartY.size()- 0.5));
        return barData;
    }

    /**
     * 得到柱狀圖(多條)
     *
     * @param barChartYs Y軸值
     * @param barNames   柱狀圖名字
     * @param barColors  柱狀圖顏色
     * @return
     */

    private BarData getBarData(List<List<Float>> barChartYs, List<String> barNames, List<Integer> barColors) {
        List<IBarDataSet> lists = new ArrayList<>();
        for (int i = 0; i < barChartYs.size(); i++) {
            ArrayList<BarEntry> entries = new ArrayList<>();

            for (int j = 0; j < barChartYs.get(i).size(); j++) {
                entries.add(new BarEntry(j, barChartYs.get(i).get(j)));
            }
            BarDataSet barDataSet = new BarDataSet(entries, barNames.get(i));

            barDataSet.setColor(barColors.get(i));
            barDataSet.setValueTextColor(barColors.get(i));
            barDataSet.setValueTextSize(10f);
            barDataSet.setAxisDependency(YAxis.AxisDependency.LEFT);
            lists.add(barDataSet);
        }
        BarData barData = new BarData(lists);

        int amount = barChartYs.size(); //需要顯示柱狀圖的類別 數量
        float groupSpace = 0.12f; //柱狀圖組之間的間距
        float barSpace = (float) ((1 - 0.12) / amount / 10); // x4 DataSet
        float barWidth = (float) ((1 - 0.12) / amount / 10 * 9); // x4 DataSet

        // (0.2 + 0.02) * 4 + 0.12 = 1.00 即100% 按照百分百佈局
        //柱狀圖寬度
        barData.setBarWidth(barWidth);
        //(起始點、柱狀圖組間距、柱狀圖之間間距)
        barData.groupBars(0, groupSpace, barSpace);
        return barData;
    }

    /**
     * 顯示混合圖(柱狀圖+折線圖)
     *
     * @param xAxisValues X軸座標
     * @param barChartY   柱狀圖Y軸值
     * @param lineChartY  折線圖Y軸值
     * @param barName     柱狀圖名字
     * @param lineName    折線圖名字
     * @param barColor    柱狀圖顏色
     * @param lineColor   折線圖顏色
     */

    public void showCombinedChart(
            List<String> xAxisValues, List<Float> barChartY, List<Float> lineChartY
            , String barName, String lineName, int barColor, int lineColor) {
        initChart();
        setXAxis(xAxisValues);

        CombinedData combinedData = new CombinedData();

        combinedData.setData(getBarData(barChartY, barName, barColor));
        combinedData.setData(getLineData(lineChartY, lineName, lineColor));
        mCombinedChart.setData(combinedData);
        mCombinedChart.invalidate();
    }

    /**
     * 顯示混合圖(柱狀圖+折線圖)
     *
     * @param xAxisValues X軸座標
     * @param barChartYs  柱狀圖Y軸值
     * @param lineChartYs 折線圖Y軸值
     * @param barNames    柱狀圖名字
     * @param lineNames   折線圖名字
     * @param barColors   柱狀圖顏色
     * @param lineColors  折線圖顏色
     */

    public void showCombinedChart(
            List<String> xAxisValues, List<List<Float>> barChartYs, List<List<Float>> lineChartYs,
            List<String> barNames, List<String> lineNames, List<Integer> barColors, List<Integer> lineColors) {
        initChart();
        setXAxis(xAxisValues);

        CombinedData combinedData = new CombinedData();

        combinedData.setData(getBarData(barChartYs, barNames, barColors));
        combinedData.setData(getLineData(lineChartYs, lineNames, lineColors));

        mCombinedChart.setData(combinedData);
        mCombinedChart.invalidate();
    }
}

但是用到組合圖的時候,遇到一個問題,就是一個組合圖中柱狀圖可以設定group,但是對應的折線圖只有一個值,這個問題github上也有人發過相應的issues,作者PhilJay本人說在3.0的版本中已經解決,但是也沒看到例子。現在我採用的是一個比較蠢的方法,用幾個第一個圖的效果“拼”出所需的效果,假如你有其他更好的方法,或者如果有人會用所說的新屬性的話,煩請告訴我一聲,不勝感激。

參考資料