1. 程式人生 > >關於MPAndroidChart 條形圖與線形圖的X軸顯示文字。

關於MPAndroidChart 條形圖與線形圖的X軸顯示文字。

     這篇文章主要是讓那些用到MPAndroidChart 卻不知道如何在X軸顯示文字的朋友看。這邊用的版本是3.0.。android studio 要整合的話 需要在app的bulid.gradle內加入

compile 'com.github.PhilJay:MPAndroidChart:v3.0.0' 這句。如果要從零開始學習MPAndroidChart 可以去看CSDN上劉某人程式設計師的MPAndroidChart系列裡面東邪,裡面東西寫的滿全的。

      手上有個專案要用到圖表,所以在網上找框架來學習 看了下hellocharts和MPAndroidChart。最終選擇了MPAndroidChart。看數十篇詳解文章後 並自己手動的去玩了下。覺得還是挺酷的。但是網上看到的文章裡面X軸(XAxis

)全部都是float型別 數字座標(時間,天數這些)。而專案內則有些圖的X軸需要是文字形式(比如名稱)。後來看原作者自己寫的DayAxisValueFormatter 實現IAxisValueFormatter 從而在X軸上顯示月份加天數。受到啟發,對Xaxis.setValueFormatter如:

xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Overridepublic String getFormattedValue(float value, AxisBase axis) {

                return

String.valueOf(data.get((int) value));

            }

            @Overridepublic int getDecimalDigits() {
                return 0;
            }
        });

東西很簡單,但是我在網上找了半天還是沒找到。然後請教了一些下寫過MPAndroidChart多篇詳解的人。他們給我的回答是要改MPAndroidChart原始碼。所以我想應該還是有很多朋友不瞭解這個東西。有些懂的朋友可能會提到

LineData lineData = new LineData(xValues, lineDataSets);這個東西好像只在2.0.幾之前有。像我用的3.0就沒了。

不多說,直接上個線形圖的簡單程式碼。

public class LineChartActivity extends BaseActivity implements OnChartGestureListener, OnChartValueSelectedListener, View.OnClickListener {

    private LineChart mLineChar;
    private LineDataSet set1;




    //顯示頂點值
private Button btn_show_values;
    //是否填滿
private Button btn_actionToggleFilled;
    //是否顯示圓點
private Button btn_actionToggleCircles;
    //切換立方
private Button btn_actionToggleCubic;
    //切換尖角/矩形
private Button btn_actionToggleStepped;
    //切換橫向立方
private Button btn_actionToggleHorizontalCubic;
    //x軸動畫
private Button btn_anim_x;
    //y軸動畫
private Button btn_anim_y;
    //xy軸動畫
private Button btn_anim_xy;
    //儲存到sd卡
private Button btn_save_sd;
    //切換自動最大最小值
private Button btn_auto_mix_max;
    private ArrayList<String> data;
    @Override
protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.layout_linechar);

        initView();
    }

    //初始化View
private void initView() {
    //模擬返回的資料名稱
        data=new ArrayList<>();
        data.add(0,"你");
        data.add(1,"瞅");
        data.add(2,"啥");
        data.add(3,"!");
        data.add(4,"瞅");
        data.add(5,"你");
        data.add(6,"咋");
        data.add(7,"地");
        //基本控制元件
btn_show_values = (Button) findViewById(R.id.btn_show_values);
        btn_show_values.setOnClickListener(this);
        btn_actionToggleFilled = (Button) findViewById(R.id.btn_actionToggleFilled);
        btn_actionToggleFilled.setOnClickListener(this);
        btn_actionToggleCircles = (Button) findViewById(R.id.btn_actionToggleCircles);
        btn_actionToggleCircles.setOnClickListener(this);
        btn_actionToggleCubic = (Button) findViewById(R.id.btn_actionToggleCubic);
        btn_actionToggleCubic.setOnClickListener(this);
        btn_actionToggleStepped = (Button) findViewById(R.id.btn_actionToggleStepped);
        btn_actionToggleStepped.setOnClickListener(this);
        btn_actionToggleHorizontalCubic = (Button) findViewById(R.id.btn_actionToggleHorizontalCubic);
        btn_actionToggleHorizontalCubic.setOnClickListener(this);
        btn_anim_x = (Button) findViewById(R.id.btn_anim_x);
        btn_anim_x.setOnClickListener(this);
        btn_anim_y = (Button) findViewById(R.id.btn_anim_y);
        btn_anim_y.setOnClickListener(this);
        btn_anim_xy = (Button) findViewById(R.id.btn_anim_xy);
        btn_anim_xy.setOnClickListener(this);
        btn_save_sd = (Button) findViewById(R.id.btn_save_sd);
        btn_save_sd.setOnClickListener(this);
        btn_auto_mix_max = (Button) findViewById(R.id.btn_auto_mix_max);
        btn_auto_mix_max.setOnClickListener(this);

        mLineChar = (LineChart) findViewById(R.id.mLineChar);
        //設定手勢滑動事件
mLineChar.setOnChartGestureListener(this);
        //設定數值選擇監聽
mLineChar.setOnChartValueSelectedListener(this);
        //後臺繪製
mLineChar.setDrawGridBackground(false);
        //設定描述文字
mLineChar.getDescription().setEnabled(false);
        //設定支援觸控手勢
mLineChar.setTouchEnabled(true);
        //設定縮放
mLineChar.setDragEnabled(true);
        //設定推動
mLineChar.setScaleEnabled(true);
        //如果禁用,擴充套件可以在x軸和y軸分別完成
mLineChar.setPinchZoom(true);
        //x軸
LimitLine llXAxis = new LimitLine(10f, "標記");
        //設定線寬
llXAxis.setLineWidth(4f);
        //
llXAxis.enableDashedLine(10f, 10f, 0f);
        //設定
llXAxis.setLabelPosition(LimitLine.LimitLabelPosition.RIGHT_BOTTOM);
        llXAxis.setTextSize(10f);

        XAxis xAxis = mLineChar.getXAxis();
        xAxis.setPosition(XAxis.XAxisPosition.BOTTOM);
        xAxis.enableGridDashedLine(10f, 10f, 0f);
        xAxis.setGranularity(1f);
        //設定x軸的最大值
xAxis.setAxisMaximum(7f);
        //設定x軸的最小值
xAxis.setAxisMinimum(0f);
        //具體實現就是這行程式碼
        xAxis.setValueFormatter(new IAxisValueFormatter() {
            @Override
public String getFormattedValue(float value, AxisBase axis) {

                return String.valueOf(data.get((int) value));

            }

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


      

        YAxis leftAxis = mLineChar.getAxisLeft();
        //重置所有限制線,以避免重疊線
leftAxis.removeAllLimitLines();
        //y軸最大
leftAxis.setAxisMaximum(200f);
        //y軸最小
leftAxis.setAxisMinimum(0f);
        leftAxis.enableGridDashedLine(10f, 10f, 0f);
        leftAxis.setDrawZeroLine(false);

        // 限制資料(而不是背後的線條勾勒出了上面)
leftAxis.setDrawLimitLinesBehindData(true);

        mLineChar.getAxisRight().setEnabled(false);

        //這裡我模擬一些資料
ArrayList<Entry> values = new ArrayList<Entry>();
        values.add(new Entry(1, 50));
        values.add(new Entry(2, 66));
        values.add(new Entry(3, 120));
        values.add(new Entry(4, 30));
        values.add(new Entry(5, 100));
        values.add(new Entry(6, 120));
        values.add(new Entry(7, 30));
        //設定資料
setData(values);

        //預設動畫
mLineChar.animateX(2500);
        //重新整理
        //mChart.invalidate();
        // 得到這個文字
Legend l = mLineChar.getLegend();

        // 修改文字 ...
l.setForm(Legend.LegendForm.LINE);
    }

    //傳遞資料集
private void setData(ArrayList<Entry> values) {
        if (mLineChar.getData() != null && mLineChar.getData().getDataSetCount() > 0) {
            set1 = (LineDataSet) mLineChar.getData().getDataSetByIndex(0);
            set1.setValues(values);
            mLineChar.getData().notifyDataChanged();
            mLineChar.notifyDataSetChanged();
        } else {
            // 建立一個數據集,並給它一個型別
set1 = new LineDataSet(values, "你瞅啥");

            // 在這裡設定線
set1.enableDashedLine(10f, 5f, 0f);
            set1.enableDashedHighlightLine(10f, 5f, 0f);
            set1.setColor(Color.BLACK);
            set1.setCircleColor(Color.BLACK);
            set1.setLineWidth(1f);
            set1.setCircleRadius(3f);
            set1.setDrawCircleHole(false);
            set1.setValueTextSize(9f);
            set1.setDrawFilled(true);
            set1.setFormLineWidth(1f);
            set1.setFormLineDashEffect(new DashPathEffect(new float[]{10f, 5f}, 0f));
            set1.setFormSize(15.f);

            if (Utils.getSDKInt() >= 18) {
                // 填充背景只支援18以上
                //Drawable drawable = ContextCompat.getDrawable(this, R.mipmap.ic_launcher);
                //set1.setFillDrawable(drawable);
set1.setFillColor(Color.YELLOW);
            } else {
                set1.setFillColor(Color.BLACK);
            }
            ArrayList<ILineDataSet> dataSets = new ArrayList<ILineDataSet>();
            //新增資料集
dataSets.add(set1);

            //建立一個數據集的資料物件
LineData data = new LineData(dataSets);

            //誰知資料
mLineChar.setData(data);
        }
    }

    @Override
public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {

    }

    @Override
public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {
        // 完成之後停止晃動
if (lastPerformedGesture != ChartTouchListener.ChartGesture.SINGLE_TAP)
            mLineChar.highlightValues(null);
    }

    @Override
public void onChartLongPressed(MotionEvent me) {

    }

    @Override
public void onChartDoubleTapped(MotionEvent me) {

    }

    @Override
public void onChartSingleTapped(MotionEvent me) {

    }

    @Override
public void onChartFling(MotionEvent me1, MotionEvent me2, float velocityX, float velocityY) {

    }

    @Override
public void onChartScale(MotionEvent me, float scaleX, float scaleY) {

    }

    @Override
public void onChartTranslate(MotionEvent me, float dX, float dY) {

    }


    @Override
public void onValueSelected(Entry e, Highlight h) {

    }

    @Override
public void onNothingSelected() {

    }

    //點選事件
@Override
public void onClick(View v) {
        switch (v.getId()) {
            //顯示頂點的值開關
case R.id.btn_show_values:
                //獲取到當前值
List<ILineDataSet> sets = mLineChar.getData().getDataSets();
                for (ILineDataSet iSet : sets) {
                    LineDataSet set = (LineDataSet) iSet;
                    //切換顯示/隱藏
set.setDrawValues(!set.isDrawValuesEnabled());
                }
                //重新整理
mLineChar.invalidate();
                break;
            //是否填滿
case R.id.btn_actionToggleFilled:
                List<ILineDataSet> setsFilled = mLineChar.getData().getDataSets();
                for (ILineDataSet iSet : setsFilled) {
                    LineDataSet set = (LineDataSet) iSet;
                    if (set.isDrawFilledEnabled())
                        set.setDrawFilled(false);
                    else
set.setDrawFilled(true);
                }
                mLineChar.invalidate();
                break;
            //是否顯示圓點
case R.id.btn_actionToggleCircles:
                List<ILineDataSet> setsCircles = mLineChar.getData().getDataSets();
                for (ILineDataSet iSet : setsCircles) {
                    LineDataSet set = (LineDataSet) iSet;
                    if (set.isDrawCirclesEnabled())
                        set.setDrawCircles(false);
                    else
set.setDrawCircles(true);
                }
                mLineChar.invalidate();
                break;
            //切換立方
case R.id.btn_actionToggleCubic:
                List<ILineDataSet> setsCubic = mLineChar.getData().getDataSets();
                for (ILineDataSet iSet : setsCubic) {
                    LineDataSet set = (LineDataSet) iSet;
                    set.setMode(set.getMode() == LineDataSet.Mode.CUBIC_BEZIER
? LineDataSet.Mode.LINEAR
: LineDataSet.Mode.CUBIC_BEZIER);
                }
                mLineChar.invalidate();
                break;
            //切換尖角/矩形
case R.id.btn_actionToggleStepped:
                List<ILineDataSet> setsStepped = mLineChar.getData().getDataSets();
                for (ILineDataSet iSet : setsStepped) {
                    LineDataSet set = (LineDataSet) iSet;
                    set.setMode(set.getMode() == LineDataSet.Mode.STEPPED
? LineDataSet.Mode.LINEAR
: LineDataSet.Mode.STEPPED);
                }
                mLineChar.invalidate();
                break;
            //切換橫向立方
case R.id.btn_actionToggleHorizontalCubic:
                List<ILineDataSet> setsHorizontalCubic = mLineChar.getData().getDataSets();
                for (ILineDataSet iSet : setsHorizontalCubic) {
                    LineDataSet set = (LineDataSet) iSet;
                    set.setMode(set.getMode() == LineDataSet.Mode.HORIZONTAL_BEZIER
? LineDataSet.Mode.LINEAR
: LineDataSet.Mode.HORIZONTAL_BEZIER);
                }
                mLineChar.invalidate();
                break;
            //x軸動畫
case R.id.btn_anim_x:
                mLineChar.animateX(3000);
                break;
            //y軸動畫
case R.id.btn_anim_y:
                mLineChar.animateY(3000, Easing.EasingOption.EaseInCubic);
                break;
            //xy軸動畫
case R.id.btn_anim_xy:
                mLineChar.animateXY(3000, 3000);
                break;
            //儲存到sd卡
case R.id.btn_save_sd:
                if (mLineChar.saveToPath("title" + System.currentTimeMillis(), "")) {
                    Toast.makeText(this, "儲存成功", Toast.LENGTH_SHORT).show();
                } else
Toast.makeText(this, "儲存失敗", Toast.LENGTH_SHORT).show();

                break;
            //切換自動最大最小值
case R.id.btn_auto_mix_max:
                mLineChar.setAutoScaleMinMaxEnabled(!mLineChar.isAutoScaleMinMaxEnabled());
                mLineChar.notifyDataSetChanged();
                break;
        }
    }

}
layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

    <com.github.mikephil.charting.charts.LineChart
android:id="@+id/mLineChar"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>

    <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">


        <Button
android:id="@+id/btn_show_values"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="頂點顯示值"/>

        <Button
android:id="@+id/btn_actionToggleFilled"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="是否填滿"/>

        <Button
android:id="@+id/btn_actionToggleCircles"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="是否顯示圓點"/>

        <Button
android:id="@+id/btn_actionToggleCubic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="切換立方"/>

    </LinearLayout>

    <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">


        <Button
android:id="@+id/btn_actionToggleStepped"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="切換尖角/矩形"/>

        <Button
android:id="@+id/btn_actionToggleHorizontalCubic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="切換橫向立方"/>

        <Button
android:id="@+id/btn_anim_x"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="X軸動畫"/>

        <Button
android:id="@+id/btn_anim_y"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Y軸動畫"/>

    </LinearLayout>

    <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">

        <Button
android:id="@+id/btn_anim_xy"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="XY軸動畫"/>

        <Button
android:id="@+id/btn_save_sd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="儲存到SD卡"/>


        <Button
android:id="@+id/btn_auto_mix_max"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="切換自動最大最小值"/>

    </LinearLayout>

</LinearLayout>