本文出自:http://blog.csdn.net/dt235201314/article/details/70237777

Demo下载(UpDating):https://github.com/JinBoy23520/MPAndroidChartDemoByJin

MPAndroidChart常见设置属性(一)——应用层  
MPAndroidChart项目实战(一)——实现对比性柱状图  
MPAndroidChart项目实战(二)——双平滑曲线(双折线图)和MarkView实现  
MPAndroidChart项目实战(三)——饼状图实现和文字重合问题解决  
MPAndroidChart项目实战(四)——柱状图实现及X轴文字不显示问题和柱状图上显示文字  
MPAndroidChart X轴文字斜着显示  
MPAndroidChart项目实战(五)——组合图实现趋势图  
MPAndroidChart项目实战(六)——自定义1MPAndroidChart滑动冲突解决(搞不定产品设计师就只能搞自己)  
MPAndroidChart项目实战(七)——自定义横向柱状图  
MPAndroidChart项目实战(八)——自定义分段堆积柱状图  
MPAndroidChart项目实战(九)——自定义带文字分段堆积柱状图  


一丶慨述

虽然在MPAndroidChart项目实战(一)里面就说了双柱状图的实现,但毕竟那是旧的jar包版,而目前的项目开发,用到的都是新版本,所以还是说一下总结一下,不整理不知道,一整理吓一跳,问题还真不少。

二丶效果:

    

三丶实现功能

1.实现柱状图。

2.解决柱状图上换行拼接文字问题。

3.解决X轴文字偶尔不显示问题。

四丶看代码

1.项目复用率很高,先得有个BarChartEntry.Java

/** * 柱状图 * Created by jin */public class BarChartEntity extends BaseChartEntity {    public BarChartEntity(BarLineChartBase chart, List[] entries, String[] labels, int[] chartColor, int valueColor, float textSize) {        super(chart, entries, labels, chartColor, valueColor, textSize);    }    @Override    protected void initChart() {        super.initChart();        mChart.getAxisLeft().setDrawGridLines(true);        mChart.getAxisLeft().enableGridDashedLine(10f, 15f, 0f);        mChart.getAxisLeft().setGridLineWidth(0.5f);        mChart.getAxisLeft().setGridColor(Color.parseColor("#f5f5f5"));        mChart.getAxisLeft().setDrawZeroLine(false);        mChart.getAxisRight().setDrawZeroLine(false);        mChart.getAxisRight().setZeroLineWidth(0f);        mChart.getAxisLeft().setZeroLineWidth(0f);        mChart.getAxisLeft().setDrawAxisLine(false);        mChart.getXAxis().setDrawAxisLine(false);        mChart.getXAxis().setAxisMinimum(0);    }    @Override    protected void setChartData() {        BarDataSet barDataSet;        if (mChart.getData() != null && mChart.getData().getDataSetCount() > 0) {            barDataSet = (BarDataSet) mChart.getData().getDataSetByIndex(0);            barDataSet.setValues(mEntries[0]);            mChart.getData().notifyDataChanged();            mChart.notifyDataSetChanged();        } else {            barDataSet = new BarDataSet(mEntries[0], labels == null ? "" : labels[0]);            barDataSet.setColors(mChartColors);            List colors = new ArrayList<>();            for (int color : mChartColors) {                colors.add(color);            }            barDataSet.setValueTextColors(colors);            ArrayList dataSets = new ArrayList<>();            dataSets.add(barDataSet);            BarData data = new BarData(dataSets);            data.setValueTextSize(mTextSize);            data.setBarWidth(0.9f);            mChart.setData(data);        }    }    public void setDrawValueAboveBar(boolean aboveBar) {        ((BarChart)mChart).setDrawValueAboveBar(aboveBar);    }    /**     * 

设置bar宽度

* @param barWidth float */ public void setBarWidth(float barWidth) { ((BarChart)mChart).getData().setBarWidth(barWidth); }}

这样就可以直接添加方法用了

/** * 柱状图 该在X轴得文字显示在柱状图上 */private void updataBarChart() {    mBarChart = (BarChart) mView.findViewById(R.id.new_the_bar_chart);    List[] entries = new ArrayList[3];    final String[] labels = {            getActivity().getResources().getString(R.string.actual_value),            getActivity().getResources().getString(R.string.budget_value),            getActivity().getResources().getString(R.string.yoy_value),};    int[] cahrtColors = {            Color.parseColor("#45A2FF"),            Color.parseColor("#58D4C5"),            Color.parseColor("#FDB25F")};    final double[] values = new double[3];    ArrayList entries1 = new ArrayList<>();    float actualValue = 10086;    float budgetValue = 1001;    float yoyValue = 12580;    entries1.add(new BarEntry(0.5f, actualValue));    entries1.add(new BarEntry(1.3f, budgetValue));    entries1.add(new BarEntry(2.1f, yoyValue));    values[0] = actualValue;    values[1] = budgetValue;    values[2] = yoyValue;    entries[0] = entries1;    if (mBarChart.getData() != null) {        mBarChart.getData().clearValues();    }    BarChartEntity barChartEntity = new BarChartEntity(mBarChart, entries, labels, cahrtColors, Color.parseColor("#999999"), 13f);    barChartEntity.setBarWidth(0.55f);    barChartEntity.setDrawValueAboveBar(true);    mBarChart.setPinchZoom(false);    mBarChart.setScaleEnabled(false);    mBarChart.animateY(2000, Easing.EasingOption.EaseInOutQuart);    barChartEntity.setAxisFormatter(new IAxisValueFormatter() {        @Override        public String getFormattedValue(float value, AxisBase axis) {            return "";        }    }, null);    mBarChart.getLegend().setEnabled(false);    /**     * 拼接柱状图上文字,涉及到修改源码     */    mBarChart.getData().setValueFormatter(new IValueFormatter() {        @Override        public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {            return labels[entry.getX() == 0.5f ? 0 : (entry.getX() == 1.3f ? 1 : 2)]                    + "\n"                    + mFormat.format(values[entry.getX() == 0.5f ? 0 : (entry.getX() == 1.3f ? 1 : 2)]);        }    });    /**     * 处理当数据都为0,不好看情况     */    float yMax = mBarChart.getData().getYMax() == 0 ? 100f : mBarChart.getData().getYMax();    float delta = yMax / 5.5f;    mBarChart.getAxisLeft().setAxisMaximum(yMax + delta);    float yMin = mBarChart.getData().getYMin();    if (yMin == 0) {        yMin = 0;    }    float deltaMin = yMin / 5.0f;    mBarChart.getAxisLeft().setAxisMinimum(yMin - deltaMin);}

代码敲完,发现没报错,但问题了来,柱状图上的文字是在同一排显,方法getFormattedValue里的“\n”,换行符并没起到作用。

此刻埋怨(该死的设计师,把那行字写在X轴出不久OK,非要整在柱状图上),初级工程师满心抓狂,大神微微一下,可能是绘图的部分出问题,找到位置


方法 public void drawValue(Canvas c, IValueFormatter formatter, float value, Entry entry, int dataSetIndex, float x, float y, int color){}用到的是paint,是不支持换行符的,那么怎么办呢,换支持的textpaint。

/**     * Draws the value of the given entry by using the provided IValueFormatter.     *     * @param c            canvas     * @param formatter    formatter for custom value-formatting     * @param value        the value to be drawn     * @param entry        the entry the value belongs to     * @param dataSetIndex the index of the DataSet the drawn Entry belongs to     * @param x            position     * @param y            position     * @param color     */    public void drawValue(Canvas c, IValueFormatter formatter, float value, Entry entry, int dataSetIndex, float x, float y, int color) {        mValuePaint.setColor(color);                //回车换行符处理        TextPaint textPaint = new TextPaint();        textPaint.setColor(mValuePaint.getColor());        textPaint.setTextSize(mValuePaint.getTextSize());        textPaint.setAntiAlias(true);        String valueTemp = formatter.getFormattedValue(value, entry, dataSetIndex, mViewPortHandler);        StaticLayout myStaticLayout = new StaticLayout(valueTemp, 0, valueTemp.length(), textPaint,                (int)textPaint.measureText(valueTemp), Layout.Alignment.ALIGN_CENTER, 1.0f, 0.0f, false);        c.save();        c.translate(x - myStaticLayout.getWidth() / 2, y - myStaticLayout.getHeight()); //开始画位置        myStaticLayout.draw(c);        c.restore();//        c.drawText(formatter.getFormattedValue(value, entry, dataSetIndex, mViewPortHandler), x, y, mValuePaint);    }
问题解决了。菜鸟此刻仰望大神,我要怎么才能像大神一样,大神微微一笑:“恶补Android 绘图部分,多读源码,Believe you can fly”

菜鸟恍然大悟,原来设计师并不是刁难自己,原来是磨练啊。


说完X轴文字放到柱状图上的,再说说,X轴显示时间段的。

看方法:

/** * X轴显示时间段的柱状图 */public void updataXBarChart(){    final MonthItemEntity entity = new MonthItemEntity();    xBarChart = (BarChart) mView.findViewById(R.id.new_x_bar_chart);    List[]entries = new ArrayList[1];    //x轴坐标 控制显示位置,并不会在X轴上显示具体的值    final float[] xlabels = new float[entity.getMonthDatas().size()];    int[] color ={Color.parseColor("#7f45a2ff")};    final String unit = "%";    //x轴坐标增量    float delta = 1;    for (int index = 0, len = entity.getMonthDatas().size(); index < len; index ++) {        xlabels[index] = index * delta + delta;    }    entries[0] = entity.getMonthEntries();    BarChartEntity barChartEntity = new BarChartEntity(xBarChart, entries, null, color, Color.parseColor("#999999"), 10f);    /*属性修改设置*/    barChartEntity.setBarWidth(0.55f);    barChartEntity.setDrawValueAboveBar(true);    xBarChart.setPinchZoom(false);    xBarChart.setScaleEnabled(false);    xBarChart.getLegend().setEnabled(false);    xBarChart.getXAxis().setTextSize(9f);    xBarChart.getAxisLeft().setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART);    mBarChart.animateY(1000, Easing.EasingOption.EaseInOutQuart);    /*X,Y坐标显示设置*/    barChartEntity.setAxisFormatter(new IAxisValueFormatter() {        @Override        public String getFormattedValue(float value, AxisBase axis) {            for (int index = 0,len = xlabels.length; index < len; index ++) {                if (value == xlabels[index]) {                    return entity.getMonthDatas().get(index).getBeginTime() + "-" + entity.getMonthDatas().get(index).getEndTime();                }            }            return "";        }    }, new IAxisValueFormatter() {        @Override        public String getFormattedValue(float value, AxisBase axis) {            return mFormat.format(value) + (unit.equals("%") ? unit : "");        }    });    /*值显示设置*/    xBarChart.getData().setValueFormatter(new IValueFormatter() {        @Override        public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) {            return mFormat.format(value) + (unit.equals("%") ? unit : "");        }    });        /*Y轴最大值最小值设置,为了尽可能的显示完整数据*/    float yMax = xBarChart.getData().getYMax() == 0 ? 100f :xBarChart.getData().getYMax();    float yDelta = yMax / 5.5f;    float axisMaximum = yMax + yDelta;    if (axisMaximum < 5) {        axisMaximum = 5;    }    xBarChart.getAxisLeft().setAxisMaximum(axisMaximum);    float yMin = xBarChart.getData().getYMin();    float deltaMin = yMin / 5.0f;    xBarChart.getAxisLeft().setAxisMinimum(yMin - deltaMin);}
理论上这样就OK了,设置了根据方法设置了XY的显示,然而X轴得文字去有一写无法显示,如效果图一。

这下有gg了,没时间还怎么用,找大神,这下大神也笑不出来了:“待我细细研究再做讨论”......

第二天,大神微微一笑,先看在显示X轴字符样式的方法里面的判断if (value == xlabels[index]),为什么我要这么去判断呢。我们知道X轴的值在显示上是平均分的,而我只有三个柱子的时候,我只要他显示三个值,所以用了xlabels[index]作为对比,只在整数位置显示拼接文字。那么问题又来了。X轴得Value是的浮点型,这样计算出柱子的平均位置就可能是浮点型,不等了自然就不显示。好了,改。

找到位置:


方法computeAxisValues(),把计算值改为int型

主要修改位置(截了修改位置的代码):

protected void computeAxisValues(float min, float max) {    float yMin = min;    float yMax = max;    int labelCount = mAxis.getLabelCount();    double range = Math.abs(yMax - yMin);    if (labelCount == 0 || range <= 0 || Double.isInfinite(range)) {        mAxis.mEntries = new float[]{};        mAxis.mCenteredEntries = new float[]{};        mAxis.mEntryCount = 0;        return;    }    // Find out how much spacing (in y value space) between axis values    int rawInterval = (int)range / labelCount;    int interval = (int)Utils.roundToNextSignificant(rawInterval);    if (interval == 0) {        interval +=1;    }    // If granularity is enabled, then do not allow the interval to go below specified granularity.    // This is used to avoid repeated values when rounding values for display.    if (mAxis.isGranularityEnabled())        interval = interval < mAxis.getGranularity() ? (int)mAxis.getGranularity() : interval;    // Normalize interval    double intervalMagnitude = Utils.roundToNextSignificant(Math.pow(10, (int) Math.log10(interval)));    int intervalSigDigit = (int) (interval / intervalMagnitude);    if (intervalSigDigit > 5) {        // Use one order of magnitude higher, to avoid intervals like 0.9 or        // 90        interval = (int)Math.floor(10 * intervalMagnitude);    }    int n = mAxis.isCenterAxisLabelsEnabled() ? 1 : 0;    // force label count    if (mAxis.isForceLabelsEnabled()) {        interval = (int) range / (int) (labelCount - 1);        mAxis.mEntryCount = labelCount;        if (mAxis.mEntries.length < labelCount) {            // Ensure stops contains at least numStops elements.            mAxis.mEntries = new float[labelCount];        }

OK,运行代码,达到图二想要效果

五丶跪求关注下载源码,200粉小目标
欢迎关注我的博客及微信公众号,后面会给大家带来更多相关MPAndroidChart无法解决的仿MPAndroidChart图标自定义控件
源码下载记得顺便Star哦~
下载链接:https://github.com/JinBoy23520/MPAndroidChartDemoByJin

更多相关文章

  1. android8.0通知
  2. Android软键盘(五)如何判断软键盘是否显示
  3. Android实现从网络获取图片显示并保存到SD卡的方法
  4. ym——Android从零开始(26)(设置全屏+横屏、相机拍照、视频录制)
  5. EditText & IME (一)
  6. Android(安卓)CoordinatorLayout 实战案例学习《二》
  7. 【转】使用Intent将图片或文字分享到新浪微博等程序
  8. android学习笔记之一常用控件
  9. singleLine=”true” 和 maxLines=”1″

随机推荐

  1. android binder 机制二(client和普通serv
  2. Android开发之颜色选择器
  3. Ubuntu 下adb连接 android 设备
  4. Android(安卓)animation - 基础
  5. Activity四种启动模式(整合)
  6. Open Core 上层代码结构
  7. Android(安卓)单个应用的内存限制
  8. Android问题:String types not allowed (a
  9. Android(安卓)两个简单线程使用示例
  10. android rom 修改订制 rom 解包 压包