MPAndroidchart two custom style text and display discontinuities in the histogram of the histogram

Description

a. text displayed on the histogram
b. discontinuous Histogram display

Prototype follows:
Here Insert Picture Description
Difficulties Description:
MPAndroidChart does not support text description information to the histogram display (bar graph); and the display node does not support pillar starting from 0.

The desired goals:
Here Insert Picture Description

Code

Note implement this code only for the histogram (BarChart)

Draw a bar graph break

Description of the histogram is described by four coordinate buffer array Barbuffer object of the four elements (left, top, right, bottom ).
In MPAndroidChart, set BarChartEntry time, each float value corresponds to a histogram by region, i.e. a continuous buffer conversion element array (shown below). To describe the histogram is now interrupted, two float values (start, detaY). It is necessary to change the mapping of the corresponding array element feed (IBarDataSet data).
Here Insert Picture Description

 @Override
    public void feed(IBarDataSet data) {

        float size = data.getEntryCount() * phaseX;
        float barWidthHalf = mBarWidth / 2f;

        for (int i = 0; i < size; i++) {

            BarEntry e = data.getEntryForIndex(i);

            if(e == null)
                continue;

            float x = e.getX();
            float y = e.getY();
            float[] vals = e.getYVals();

            if (!mContainsStacks || vals == null) {
            	...
            } else {

                float posY = 0f;
                float negY = -e.getNegativeSum();
                float yStart = 0f;
                if(e.isPresentOneData()){
                    checkData(vals);
                }

                // fill the stack
                for (int k = 0; k < vals.length; k++) {

                    float value = vals[k];

                    if (value == 0.0f && (posY == 0.0f || negY == 0.0f)) {
                        // Take care of the situation of a 0.0 value, which overlaps a non-zero bar
                        y = value;
                        yStart = y;
                    } else if (value >= 0.0f) {
                        y = posY;
                        yStart = posY + value;
                        posY = yStart;
                    } else {
                        y = negY;
                        yStart = negY + Math.abs(value);
                        negY += Math.abs(value);
                    }

                    float left = x - barWidthHalf;
                    float right = x + barWidthHalf;
                    float bottom, top;

                    if (mInverted) {
                        bottom = y >= yStart ? y : yStart;
                        top = y <= yStart ? y : yStart;
                    } else {
                        top = y >= yStart ? y : yStart;
                        bottom = y <= yStart ? y : yStart;
                    }

                    // multiply the height of the rect with the phase
                    top *= phaseY;
                    bottom *= phaseY;
					//两个float元素对应一个 bar区域
                    if(k==0&&e.isPresentOneData()){

                    }else{
                        addBar(left, top, right, bottom);
                    }
                }
            }
        }

        reset();
    }

Draw text descriptions

Excellent MPAndroidChart design is very friendly. Set aside a drawExtras (Canvas c) interface DataRenderer interface that allows developers to customize the content. And the text displayed on the histogram, the business logic is implemented in the method.
Here Insert Picture Description
This reference DrawValue conventional method, write a description of the function information

 @Override
    public void drawExtras(Canvas c) {
        // if values are drawn
        List<IBarDataSet> dataSets = mChart.getBarData().getDataSets();

        final float valueOffsetPlus = Utils.convertDpToPixel(4.5f);
        float posOffset = 0f;

        for (int i = 0; i < mChart.getBarData().getDataSetCount(); i++) {

            IBarDataSet dataSet = dataSets.get(i);

            if (!dataSet.isDrawDesEnabled())
                continue;

            // apply the text-styling defined by the DataSet
            applyDesTextStyle(dataSet);

            // calculate the correct offset depending on the draw position of
            // the value
            float valueTextHeight = Utils.calcTextHeight(mDesPaint, "8");
            posOffset = valueTextHeight + valueOffsetPlus;


            // get the buffer
            BarBuffer buffer = mBarBuffers[i];

            MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
            iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
            iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);


            int bufferIndex = 0;
            int index = 0;

            while (index < dataSet.getEntryCount() * mAnimator.getPhaseX()) {

                BarEntry entry = dataSet.getEntryForIndex(index);

                float[] vals = entry.getYVals();
                float x = (buffer.buffer[bufferIndex] + buffer.buffer[bufferIndex + 2]) / 2f;

                int color = dataSet.getDesTextColor(index);

                if (!mViewPortHandler.isInBoundsRight(x))
                    break;

                if (!mViewPortHandler.isInBoundsY(buffer.buffer[bufferIndex + 3])
                        || !mViewPortHandler.isInBoundsLeft(x))
                    continue;
                //核心代码 如果开始描述文字的功能,则渲染文字
                if (dataSet.isDrawDesEnabled()) {
                    //检查空间
                    if(buffer.buffer[bufferIndex+3]-buffer.buffer[bufferIndex+1]>4+posOffset){
                        drawDes(c, entry.getDes(), x, buffer.buffer[bufferIndex + 3] - posOffset,
                                color);
                    }else {
                        drawDes(c, entry.getDes(), x, buffer.buffer[bufferIndex + 3] +
                                        posOffset,
                                color);
                    }

                }

                // draw stack values
                bufferIndex = vals == null ? bufferIndex + 4 : bufferIndex + 4 * (entry.isPresentOneData()?1:vals.length);
                index++;
            }

            MPPointF.recycleInstance(iconsOffset);
        }
    }

Handle touch events

In MPAndroidChart in, onTouch event will eventually be applied to Range objects. And when defining BarChartEntry, if passed in the Float [] array, each element will be converted to a Range object. However, intermittent but data is expressed, it is necessary to describe the two float a target range. Specific modifications are as follows:
Here Insert Picture Description

use

//a.设置BarEntry的步骤
ArrayList<BarEntry> barEntries = new ArrayList<>();
        //1.链式调用
        //1.1 注意,在new float[]{ 0, 0.21111f }数组中,第一个元素代表柱状图的起始位置;
        //第二个元素代码柱状图的高度值
        barEntries.add(new BarEntry(1, new float[]{ 0, 0.21111f })		
        //2.设置是否是float[2] 展示一个数据
                .setPresentOneData(true)
      	//3. 设置文本描述信息         
                .setmDes("12.3%"));
        barEntries.add(new BarEntry(2,new float[]{0.11111f,0.3f})
                .setPresentOneData(true)
                .setmDes("12.3%"));
       	...
       	...
        barEntries.add(new BarEntry(6, new float[]{1,1.3f})
                .setPresentOneData(true)
                .setmDes("12.3%"));
//b.设置BarDataSet的步骤
        BarDataSet barDataSet = new BarDataSet(barEntries, "error times").setDrawDesEnable(true);
        //设置描述字体的颜色
        barDataSet.setmDesColor(Color.RED);

Code Portal

Published 98 original articles · won praise 6 · views 20000 +

Guess you like

Origin blog.csdn.net/dirksmaller/article/details/103978271