MPAndroidChart--关于数据如果存在0的情况,曲线图会断开,连线中间会有线条未显示

168 阅读2分钟

最近的需求,突然又有图表库了,上一次写折线图曲线图这一类图表,还是7年前的需求,先看看类似的图例

image.png

image.png

从图可以看出来,当数据是0的时候,会出现线断开了,不连续的样子

全网找遍了,都没找到对应的代码,今天来总结归纳一下

1.我们再使用的过程中,都会去设置,这个图表,你是用曲线图还是折线图还是阶梯图,该问题,就是用了曲线图,  才出现的bug

       //设置曲线展示为圆滑曲线(如果不设置则默认折线)
        lineDataSet.setMode(LineDataSet.Mode.CUBIC_BEZIER);
        lineDataSet.setDrawHighlightToMax(false);`
  1. 点击进去后,能看到他里面是一个枚举类型

image.png

3.进一步查看调用地方

image.png

点击查看 发现源码这个地方是这么写的

  switch (dataSet.getMode()) {
            default:
            case LINEAR:
            case STEPPED:
                drawLinear(c, dataSet);
                break;
 
            case CUBIC_BEZIER:
                drawCubicBezier(dataSet);
                break;
 
            case HORIZONTAL_BEZIER:
                drawHorizontalBezier(dataSet);
                break;
        }

关键代码就是这个 

drawCubicBezier(XXXXX)

修改源码来满足需求:

这里增加一个 ,

boolean isPrevZero = false;  // 上一个点的Y值是否为0
    protected void drawCubicBezier(ILineDataSet dataSet) {
 
        float phaseY = mAnimator.getPhaseY();
 
        Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
 
        mXBounds.set(mChart, dataSet);
 
        float intensity = dataSet.getCubicIntensity();
 
        cubicPath.reset();
 
        if (mXBounds.range >= 1) {
 
            float prevDx = 0f;
            float prevDy = 0f;
            float curDx = 0f;
            float curDy = 0f;
            boolean isPrevZero = false;  // 上一个点的Y值是否为0
 
            // Take an extra point from the left, and an extra from the right.
            // That's because we need 4 points for a cubic bezier (cubic=4), otherwise we get lines moving and doing weird stuff on the edges of the chart.
            // So in the starting `prev` and `cur`, go -2, -1
            // And in the `lastIndex`, add +1
 
            final int firstIndex = mXBounds.min + 1;
            final int lastIndex = mXBounds.min + mXBounds.range;
 
            Entry prevPrev;
            Entry prev = dataSet.getEntryForIndex(Math.max(firstIndex - 2, 0));
            Entry cur = dataSet.getEntryForIndex(Math.max(firstIndex - 1, 0));
            Entry next = cur;
            int nextIndex = -1;
 
            if (cur == null) return;
 
            // let the spline start
            cubicPath.moveTo(cur.getX(), cur.getY() * phaseY);
 
            for (int j = mXBounds.min + 1; j <= mXBounds.range + mXBounds.min; j++) {
 
                prevPrev = prev;
                prev = cur;
                cur = nextIndex == j ? next : dataSet.getEntryForIndex(j);
 
                nextIndex = j + 1 < dataSet.getEntryCount() ? j + 1 : j;
                next = dataSet.getEntryForIndex(nextIndex);
 
                // 判断上一个点的Y值是否为0
                if (prev.getY() == 0f && !isPrevZero) {
                    cubicPath.lineTo(cur.getX(), cur.getY() * phaseY); // 将当前点与上一个点(Y值为0)连接
                    isPrevZero = true;
                } else {
                    isPrevZero = false;
                }
 
                prevDx = (cur.getX() - prevPrev.getX()) * intensity;
                prevDy = (cur.getY() - prevPrev.getY()) * intensity;
                curDx = (next.getX() - prev.getX()) * intensity;
                curDy = (next.getY() - prev.getY()) * intensity;
 
                cubicPath.cubicTo(prev.getX() + prevDx, (prev.getY() + prevDy) * phaseY,
                        cur.getX() - curDx,
                        (cur.getY() - curDy) * phaseY, cur.getX(), cur.getY() * phaseY);
            }
        }
 
        // if filled is enabled, close the path
        if (dataSet.isDrawFilledEnabled()) {
 
            cubicFillPath.reset();
            cubicFillPath.addPath(cubicPath);
 
            drawCubicFill(mBitmapCanvas, dataSet, cubicFillPath, trans, mXBounds);
        }
 
        mRenderPaint.setColor(dataSet.getColor());
 
        mRenderPaint.setStyle(Paint.Style.STROKE);
 
        trans.pathValueToPixel(cubicPath);
 
        mBitmapCanvas.drawPath(cubicPath, mRenderPaint);
 
        mRenderPaint.setPathEffect(null);
    }
```

处理后的效果图,完美解决问题

image.png image.png