MPAndroidChart HorizontalBarChart X轴自定义

由于项目要有一个品种分析功能,显示推荐品种,因此选择使用MPAndroidChart,以图表形式表现比较直观。效果如图所示。

MPAndroidChart HorizontalBarChart X轴自定义_第1张图片

先上代码:

AnalysisActivity.java:

package com.XXX.Activity;

import android.os.Bundle;

import com.github.mikephil.charting.charts.BarChart;
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.BarData;
import com.github.mikephil.charting.data.BarDataSet;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;

import com.XXX.Activity.Util.BaseActivity;
import com.XXX.MyView.Chart.MyXFormatter;
import com.XXX.R;

import java.util.ArrayList;

public class AnalysisActivity extends BaseActivity
{
    protected BarChart mChart;       //图
    private int sCount = 12;         //X轴坐标数据数量

    private ArrayList data//保存X轴坐标数据

    @Override
    protected void onCreate(Bundle savedInstanceState)
    {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_analysis);
        mActionBar.setTitle(getString(R.string.s_analysis));

        mChart = findViewById(R.id.bc_re);

        mChart.setDrawBarShadow(false);
        mChart.setDrawValueAboveBar(true);
        //mChart.setContentDescription("××表");
        mChart.getDescription().setEnabled(false);
        mChart.setNoDataText(getString(R.string.s_no_data));
        mChart.setPinchZoom(false);  //scaling can now only be done on x- and y-axis separately
        mChart.setDrawGridBackground(false);
        mChart.getAxisRight().setEnabled(false);  //不绘制右侧轴线

        data = new ArrayList<>();
        for(int i = 0; i<sCount ; i++)
        {
            data.add("ca"+(i+1));
        }

        XAxis xl = mChart.getXAxis();
        xl.setValueFormatter(new MyXFormatter(data));
        xl.setPosition(XAxis.XAxisPosition.BOTTOM);
        //xl.setLabelRotationAngle(45);  //标签倾斜
        xl.setDrawAxisLine(true);
        xl.setDrawGridLines(false);
        xl.setCenterAxisLabels(false);  //可不加这句,默认为false
        //xl.setGranularity(sCount);  //x轴坐标占的宽度
        xl.setGranularity(1f);        //x轴坐标占的宽度
        //xl.setCenterAxisLabels(true);
        xl.setAxisMinimum(-0.5f);  // 此轴显示的最小值
        //xl.setAxisMaximum(sCount*sCount);  // 此轴显示的最大值
        xl.setLabelCount(sCount);    //显示的坐标数量

        YAxis yl = mChart.getAxisLeft();
        yl.setDrawAxisLine(true);
        yl.setDrawGridLines(true);
        yl.setAxisMinimum(0f);  //this replaces setStartAtZero(true)

        float[] val = {24, 35 , 73.6f, 94.2f, 23, 6, 86, 55, 44.4f, 77.77f, 0, 33};
        setData(sCount, val);
        mChart.setFitBars(true);
        mChart.animateXY(2000, 2000);

        Legend legend = mChart.getLegend();
        legend.setEnabled(false);  //不显示图例
    }

    private void setData(int count, float[] val)
    {
        //float barWidth = count-1;    //每个彩色数据条的宽度
        //float spaceForBar = count;   //每个数据条实际占的宽度
        float barWidth = 0.8f;        //每个彩色数据条的宽度
        float spaceForBar = 1f;       //每个数据条实际占的宽度
        ArrayList yVals1 = new ArrayList();

        for (int i = 0; i < count; i++)
        {
            //float val = (float) (Math.random() * range);
            yVals1.add(new BarEntry(i * spaceForBar, val[i],
                    getResources().getDrawable(R.drawable.ic_add_a_photo)));
        }

        BarDataSet set1;

        if (mChart.getData() != null && mChart.getData().getDataSetCount() > 0)
        {
            set1 = (BarDataSet)mChart.getData().getDataSetByIndex(0);
            set1.setValues(yVals1);
            mChart.getData().notifyDataChanged();
            mChart.notifyDataSetChanged();
        }
        else
        {
            set1 = new BarDataSet(yVals1, "XXXX");

            set1.setDrawIcons(false);

            ArrayList dataSets = new ArrayList();
            dataSets.add(set1);

            BarData data = new BarData(dataSets);
            data.setValueTextSize(10f);
            data.setBarWidth(barWidth);
            mChart.setData(data);
        }
    }
}

 

MyXFormatter.java:
package com.XXX.MyView.Chart;

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

import java.util.List;

public class MyXFormatter implements IAxisValueFormatter
{
    private List mValues;

    public MyXFormatter(List values)
    {
        this.mValues = values;
    }

    @Override
    public String getFormattedValue(float value, AxisBase axis)
    {
       if(((int)value >=0 && (int)value < mValues.size()))
            return mValues.get((int) value);
       else
            return "";
    }
}

 

activity_analysis.xml:

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

    <com.github.mikephil.charting.charts.HorizontalBarChart
        android:id="@+id/bc_re"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

LinearLayout>

 

分析:

按照示例代码来写,本来以为比较简单的功能,没想到卡在X轴自定义上。总是不能在正确的地方显示坐标。主要原因在于MyXFormatter 中 getFormattedValue() 方法中的参数value,到现在也没弄明白value的分段(增长)机制,github上的Issues

https://github.com/PhilJay/MPAndroidChart/issues/2693

https://github.com/PhilJay/MPAndroidChart/issues/3894

也无人回答。

当将代码中红色行改成注释掉的值时,发现当sCount<=10value的增长幅度为10,当sCount>10value的增长幅度为sCount。最后采取了

https://stackoverflow.com/questions/43027652/mpandroidchart-xaxis-values-not-corresponding-to-data-values

的答案,行了。


 

 



你可能感兴趣的:(android,java)