饼图不显示百分比(%),显示原始数据的处理

需求:做一个饼图,在显示数据的时候不显示百分比样式,而是要显示原来的数据,UI如下:
饼图不显示百分比(%),显示原始数据的处理_第1张图片

拿到需求后时看到 MPAndroidChart 这个开源框架,然后就下载了 demo 看着和需求是高度吻合(此时还不知道需求要显示原始数字数据),然后就拿过来直接做了,等做完了需求说要在饼图上显示原始数据,从提供的 api 里找了半天也没找到怎么修改,后来在网上找到一种方法挺好用的,就整理了一下。


处理方法:不使用 Pie Chart 原始的数据格式 PercentFormatter,根据 [PercentFormatter] 的样式重新写一个,使用

pieData.setValueFormatter(new DefaultValueFormate("万"))

替换 :

pieData.setValueFormatter(new PercentFormatter());

就正常了,示例图可以看上面的UI。




部分代码如下:

自定义数据格式类 PercentFormatter(可根据需要自行修改):


import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.formatter.IValueFormatter;
import com.github.mikephil.charting.utils.ViewPortHandler;
import java.text.DecimalFormat;

public class DefaultValueFormate implements IValueFormatter {
     

    /**
     * DecimalFormat for formatting
     */
    protected DecimalFormat mFormat;
    public DefaultValueFormate() {
     
        setup("");
    }

    /**
     * @param endDes 数字后添加的 单位
     */
    public DefaultValueFormate(String endDes) {
     
        setup(endDes);
    }
    
    private void setup(String endDes) {
     
        if (TextUtils.isEmpty(endDes)) {
     
            // ###.## 表示可以精确到小数点后两位,即 double 类型
            mFormat = new DecimalFormat("###.##");
        } else {
     
            mFormat = new DecimalFormat("###.##" + endDes);
        }
    }

    @Override
    public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {
     
        return mFormat.format(value);
    }

    /**
     * Returns the number of decimal digits this formatter uses.
     * @return
     */
    public int getDecimalDigits() {
     
        return 1;
    }
}

使用代码如下:

// 设置 pie chart
 public void setPieChart() {
     
        pieChart.getDescription().setEnabled(false);//设置描述
        pieChart.setExtraOffsets(25, 10, 25, 25); //设置边距
        pieChart.setDragDecelerationFrictionCoef(0.1f);//设置摩擦系数(值越小摩擦系数越大)
        pieChart.setRotationEnabled(true);//是否可以旋转
        pieChart.setDrawCenterText(false);//设置绘制环中文字
        //这个方法为true就是环形图,为false就是饼图
        pieChart.setDrawHoleEnabled(false);

        pieChart.animateY(1200, Easing.EaseInOutQuad);

//TODO 设置 legend
        Legend l = pieChart.getLegend();
        l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
        l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
        l.setOrientation(Legend.LegendOrientation.VERTICAL);
        l.setDrawInside(false);
        l.setXEntrySpace(0f);
        l.setYEntrySpace(0f);
        l.setYOffset(0f);
        l.setTextSize(15f);
        l.setTextColor(Color.parseColor("#e3d321"));

        //设置饼图数据
        setPieChartData();
    }
    
//TODO 设置 数据
    private void setPieChartData() {
     

        List<PieEntry> entries = new ArrayList<>();
        entries.add(new PieEntry(300f,"金融"));
        entries.add(new PieEntry(600f,"基金"));
        entries.add(new PieEntry(1200f,"黄金"));
        entries.add(new PieEntry(150,"收支"));
        PieDataSet dataSet = new PieDataSet(entries, "");

        ArrayList<Integer> colors = new ArrayList<>();

        colors.add(Color.rgb(221,131,241));
        colors.add(Color.rgb(242,173,173));
        colors.add(Color.rgb(53,186,232));
        colors.add(Color.rgb(0,205,131));

        dataSet.setColors(colors);//设置饼块的颜色

        //设置数据显示方式有见图
        dataSet.setValueLinePart1OffsetPercentage(80f);//数据连接线距图形片内部边界的距离,为百分数
        dataSet.setValueLinePart1Length(0.3f);
        dataSet.setValueLinePart2Length(0.4f);
        dataSet.setValueLineColor(Color.YELLOW);//设置连接线的颜色
        dataSet.setYValuePosition(PieDataSet.ValuePosition.OUTSIDE_SLICE);
        PieData pieData = new PieData(dataSet);
        pieData.setValueTextSize(11f);
        pieData.setValueTextColor(Color.DKGRAY);

//TODO 设置不显示百分比时,如果是数字会在数字后面自动添加了一个%,这个是在源码中写的,有兴趣可以看看
        pieChart.setUsePercentValues(false); 
        //使用下面的格式替换 PercentFormatter
//        pieData.setValueFormatter(new PercentFormatter());
        pieData.setValueFormatter(new DefaultValueFormate("万"));//自己修改的方法

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

到此处显示原始数据的问题就圆满解决了。



本以为这样就结束了,然而并没有。。。。。。

需求又说了,还要给饼图中的每一个扇形添加点击页面跳转事件,然后就找到了下面这个方法:

pieChart.setOnChartValueSelectedListener(new OnChartValueSelectedListener() {
     
            @Override
            public void onValueSelected(Entry e, Highlight h) {
     
            }

            @Override
            public void onNothingSelected() {
     
            }
        });

测试的时候发现这个点击事件是有效的,并且还能让该点击的扇形区域有一个放大效果,但是,回到饼图页面的时候发现再次点击饼图,执行了 OnChartValueSelectedListeneronNothingSelected() 方法,没有执行 onValueSelected(Entry e, Highlight h)方法,要再点击一次才能执行 onValueSelected(Entry e, Highlight h) 方法,一开始以为是因为这个 Highlighting(github 官网有说明) 这个属性导致的,然后就把这个东西使用下面方式给关闭:

        pieChart.setHighlightPerTapEnabled(false);

关掉之后,这个“放大”的效果确实没有了,但是扇形区域的点击事件也没有了。
通过 pieChart 的 setOnChartValueSelectedListener 这个方法找到 chart 类中的源码:


    /**
     * Highlights the value selected by touch gesture. Unlike
     * highlightValues(...), this generates a callback to the
     * OnChartValueSelectedListener.
     *
     * @param high         - the highlight object
     * @param callListener - call the listener
     */
    public void highlightValue(Highlight high, boolean callListener) {
     

        Entry e = null;

        if (high == null)
            mIndicesToHighlight = null;
        else {
     

            if (mLogEnabled)
                Log.i(LOG_TAG, "Highlighted: " + high.toString());

            e = mData.getEntryForHighlight(high);
            if (e == null) {
     
                mIndicesToHighlight = null;
                high = null;
            } else {
     

                // set the indices to highlight
                mIndicesToHighlight = new Highlight[]{
     
                        high
                };
            }
        }

        setLastHighlighted(mIndicesToHighlight);

        if (callListener && mSelectionListener != null) {
     

            if (!valuesToHighlight())
                mSelectionListener.onNothingSelected();
            else {
     
                // notify the listener
                mSelectionListener.onValueSelected(e, high);
            }
        }

        // redraw the chart
        invalidate();
    }

接着就对这个方法在进行设置,发现没有起作用,目前还没解决这个问题,看到这是不是很郁闷,没解决还写这么长[顺着网线来找我吧],好吧,就是记录一下,以后要是找到解决方法的话再来完善,或者有好的方法的话可以提供一下。

你可能感兴趣的:(Android,Pie,Chart)