1. 程式人生 > >MpAndroid 柱狀圖詳解

MpAndroid 柱狀圖詳解

1. 問題出現

   最近專案資料繁多,要做一些圖示實現資料視覺化。自己寫可以實現但耗費時間長,所以找了下各種Charts的開源專案,最後找到了MpAndroidChart。它的文件比較詳細,擴充套件性好一點,所以今天寫一下MpAndroidChartd的使用。

2. 問題分析

網上各種MpAndroidChart的介紹,有翻譯英文文件,也有介紹圖表某一個屬性,但針對某一種圖表的詳細介紹很少,今天就介紹下柱狀圖的所有元素(包括X軸、Y軸、Value值自定義等)的使用吧!

下面上今天要講的圖表截圖:


(1)Build.gradle依賴及使用前Xml定義

compile 'com.github.PhilJay:MPAndroidChart:v3.0.0'
<com.github.mikephil.charting.charts.BarChart
        android:id="@+id/mBarChart"
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1"/>

(2)BarChart初始化及一些常規設定:

        //柱狀圖
        mBarChart = (BarChart) findViewById(R.id.mBarChart);
        //設定柱狀圖點選的時候,的回撥函式
        mBarChart.setOnChartValueSelectedListener(this);
        //柱狀圖的陰影
        mBarChart.setDrawBarShadow(false);
        //設定柱狀圖Value值顯示在柱狀圖上方 true 為顯示上方,預設false value值顯示在柱狀圖裡面
        mBarChart.setDrawValueAboveBar(true);
        //Description Label 是否可見
        mBarChart.getDescription().setEnabled(false);
        // 設定最大可見Value值的數量 針對於ValueFormartter有效果
        mBarChart.setMaxVisibleValueCount(60);
        // 二指控制X軸Y軸同時放大
        mBarChart.setPinchZoom(false);
        //是否顯示錶格背景顏色
        mBarChart.setDrawGridBackground(false);
        //設定X軸顯示文字旋轉角度-60意為逆時針旋轉60度
        mBarChart.getXAxis().setLabelRotationAngle(-60);

(3)X軸的設定及自定義X

        XAxis xAxis = mBarChart.getXAxis();
        //設定X軸顯示位置
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        //X軸縱向分割線,一般不設定顯示
        xAxis.setDrawGridLines(false);
        // X軸顯示Value值的精度,與自定義X軸返回的Value值精度一致
        xAxis.setGranularity(1f);
        //X軸橫座標顯示的數量
        xAxis.setLabelCount(7);
        //X軸最大座標
        xAxis.setAxisMaximum(6f);
        //X軸最小座標
        xAxis.setAxisMinimum(0.5f);

X軸自定義需要設定valuformatter,如上述程式碼,我們控制了X軸的座標範圍為0.5-6X軸可顯示的label數為7個數,X軸精度為1,那麼如果沒有自定義,X軸的顯示效果為:

應該顯示0-6六個數,但我設定的最小起始座標為0.5f,所以X軸座標0不可見,理解了這個自定義X軸就好辦了,自定義XCallCountFormatter類程式碼為:

public class CallCountFormatter implements IAxisValueFormatter {
    private final BarLineChartBase<?> mChart;
    public CallCountFormatter(BarLineChartBase<?> chart) {
        this.mChart = chart ;

    }
    @Override
    public String getFormattedValue(float value, AxisBase axis) {
        Log.i(TAG,"getFormattedValue-------------"+value);

        Log.i(TAG,"mChart.getVisibleXRange()-------------"+mChart.getVisibleXRange());
        if(value==0.0 || value == 6.0){
            return "" ;
        }else {
            return "13685624925";
        }
    }
    @Override
    public int getDecimalDigits() {
        return 0;
    }
}

自定義X軸後我們可以通過getFormattedValue()方法自行處理Value值,這裡Value返回的值為0.0-6.0 Float值 ,我們只需要在1.0-5.05個位置顯示我們自己的值就可以,其他位置不顯示X軸值,返回””(不能返回null,不然會報錯),顯示效果為


這裡自定義X軸就基本完成了,至於具體每個座標點想顯示不同的號碼,可以自行去調整

(4)Y軸初始化及自定義Y軸:

        //Y左邊軸
        YAxis leftAxis = mBarChart.getAxisLeft();
        //設定Y左邊軸顯示的值 label 數量
        leftAxis.setLabelCount(8, false);
        //設定值顯示的位置,我們這裡設定為顯示在Y軸外面
        leftAxis.setPosition(YAxis.YAxisLabelPosition.OUTSIDE_CHART);
        //設定Y軸 與值的空間空隙 這裡設定30f意為30%空隙,預設是10%
        leftAxis.setSpaceTop(30f);
        //設定Y軸最小座標和最大座標
        leftAxis.setAxisMinimum(0f);
        leftAxis.setAxisMaximum(80f);

        //Y軸右邊軸的設定,跟左邊軸類似
        YAxis rightAxis = mBarChart.getAxisRight();
        rightAxis.setDrawGridLines(false);
        rightAxis.setLabelCount(8, false);
        rightAxis.setSpaceTop(30f);
        rightAxis.setAxisMinimum(0f);
        rightAxis.setAxisMaximum(80f);

顯示效果為:


自定義Y軸與X軸類似,也要設定ValueFormatter

leftAxis.setValueFormatter(new BarLeftYValueFormatter());

需要實現IAxisValueFormatter 介面,

BarLeftYValueFormatter類程式碼如下:

public class BarLeftYValueFormatter implements IAxisValueFormatter {
    @Override
    public String getFormattedValue(float value, AxisBase axis) {

        return value+"";
    }

    @Override
    public int getDecimalDigits() {
        return 0;
    }
}

實現效果如圖:


這裡返回值我們控制了左邊Y顯示Float值,如果想要右邊Y軸自定義,同樣設定valueFormatter值就好

(5)柱狀圖表格標示Legend的設定:

        // 設定表格標示的位置
        Legend l = mBarChart.getLegend();
        //標示坐落再表格左下方
        l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM);
        l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT);
        //標示水平朝向
        l.setOrientation(Legend.LegendOrientation.HORIZONTAL);
        //標示在表格外
        l.setDrawInside(false);
        //樣式
        l.setForm(Legend.LegendForm.SQUARE);
        //字型
        l.setFormSize(9f);
        //大小
        l.setTextSize(11f);

顯示效果如下:


(6)表格資料填充

        //模擬資料
        ArrayList<BarEntry> yVals1 = new ArrayList<BarEntry>();
        yVals1.add(new BarEntry(1.2f, 10));
        yVals1.add(new BarEntry(2.2f, 20));
        yVals1.add(new BarEntry(3.2f, 30));
        yVals1.add(new BarEntry(4.2f, 40));
        yVals1.add(new BarEntry(5.2f, 50));

        BarDataSet set1;
        if (mBarChart.getData() != null &&
                mBarChart.getData().getDataSetCount() > 0) {
            set1 = (BarDataSet) mBarChart.getData().getDataSetByIndex(0);
            set1.setValues(yVals1);
            mBarChart.getData().notifyDataChanged();
            mBarChart.notifyDataSetChanged();
        } else {
            set1 = new BarDataSet(yVals1, "號碼聯絡次數統計");
            //設定有四種顏色
            set1.setColors(ColorTemplate.MATERIAL_COLORS);
            ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
            dataSets.add(set1);
            BarData data = new BarData(dataSets);
            data.setValueTextSize(10f);
            data.setBarWidth(0.6f);
            data.setValueFormatter(new CallCountValueFormatter());
            //設定資料
            mBarChart.setData(data);
        }

(7)頂點Value值自定義:

如上程式碼Value值自定義需要對傳入的data設定ValueFormatter

CallCountValueFormatter類程式碼如下:

public class CallCountValueFormatter implements IValueFormatter {
    @Override
    public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
        int i  = (int) value;
        return i+"次";
    }
}

實現效果如圖:


(8)拓展:Value值顯示非數字資訊,多系列柱狀圖

a) Value值顯示非數字資訊:

最近有需求需要柱狀圖value值顯示非數字類的資訊,這時候我們就要用到BarEntry的另一個構造方法

public BarEntry(float x, float y, Object data) {
        super(x, y, data);
    }

傳入我們自己想要的object資料了,如下程式碼:

yVals1.add(new BarEntry(1.2f, 10,"微信"));
        yVals1.add(new BarEntry(2.2f, 20,"qq"));
        yVals1.add(new BarEntry(3.2f, 30,"陌陌"));
        yVals1.add(new BarEntry(4.2f, 40,"百度"));
        yVals1.add(new BarEntry(5.2f, 50,"支付寶"));

傳入自定義的資料後,valueformatter就可以拿到資料:

public class CallCountValueFormatter implements IValueFormatter {

    @Override

    public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {

        String data = (String) entry.getData();

        return data;

    }

}

效果圖如下:


a) 多系列柱狀圖:

效果圖如下:


X軸、Y軸、Value值的設定前面都提到過,除此,還需要控制柱狀圖的顏色,控制顏色只需要傳入自定義的顏色陣列即可:

set1 = new BarDataSet(yVals1, "App使用記錄統計");
            //設定有四種顏色
            set1.setColors(ints);
            ArrayList<IBarDataSet> dataSets = new ArrayList<IBarDataSet>();
            dataSets.add(set1);
            BarData data = new BarData(dataSets);
            data.setValueTextSize(10f);
            data.setBarWidth(0.6f);

Ints顏色陣列0-2位一個顏色,3-5一個顏色,6-8一個顏色,具體的由於篇幅就不再贅述。

總之,柱狀圖的大體要用到的一些關鍵屬性這裡都介紹了,大家有什麼問題,可以給我留言,我儘量解答。


github原始碼