项目中有个需求,使用的是折线图,但是要求当y轴的值为0的时候 不与前后的点进行连接,但是MpChart 默认是完全连接的。
我需要的效果是这样的
下面说实现方式:
LineDataSet支持设置渲染模式 默认是以下几种(其中第一个是笔者自己添加的,为了实现图2的效果)
public enum Mode {
/**
* 这个zero是我根据需求自己添加的
*/
LINEAR_DISCONNECT_ZERO,
LINEAR,
STEPPED,
CUBIC_BEZIER,
HORIZONTAL_BEZIER
}
图表的绘制在LineChartRenderer类中,
switch (dataSet.getMode()) {
default:
case LINEAR:
case STEPPED:
drawLinear(c, dataSet);
break;
case LINEAR_DISCONNECT_ZERO:
drawLinearDisConnectZero(c,dataSet);
break;
case CUBIC_BEZIER:
drawCubicBezier(dataSet);
break;
case HORIZONTAL_BEZIER:
drawHorizontalBezier(dataSet);
break;
}
自己创建的绘制方法 其实重点就是 y值为0的话跳出 绘制 ( //实现这个效果重点就是这行代码
if (e1.getY()==0||e2.getY()==0) continue;)
private void drawLinearDisConnectZero(Canvas c, @NonNull ILineDataSet dataSet) {
int entryCount = dataSet.getEntryCount();
final int pointsPerEntryPair = 2;
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
float phaseY = mAnimator.getPhaseY();
mRenderPaint.setStyle(Paint.Style.STROKE);
Canvas canvas = c;
mXBounds.set(mChart, dataSet);
// if drawing filled is enabled
// if (dataSet.isDrawFilledEnabled() && entryCount > 0) {
// drawLinearFill(c, dataSet, trans, mXBounds);
// }
// more than 1 color
if (dataSet.getColors().size() > 1) {
if (mLineBuffer.length <= pointsPerEntryPair * 2)
mLineBuffer = new float[pointsPerEntryPair * 4];
for (int j = mXBounds.min; j <= mXBounds.range + mXBounds.min; j++) {
Entry e = dataSet.getEntryForIndex(j);
if (e == null) continue;
mLineBuffer[0] = e.getX();
mLineBuffer[1] = e.getY() * phaseY;
if (j < mXBounds.max) {
e = dataSet.getEntryForIndex(j + 1);
if (e == null) break;
mLineBuffer[2] = e.getX();
mLineBuffer[3] = e.getY() * phaseY;
} else {
mLineBuffer[2] = mLineBuffer[0];
mLineBuffer[3] = mLineBuffer[1];
}
trans.pointValuesToPixel(mLineBuffer);
if (!mViewPortHandler.isInBoundsRight(mLineBuffer[0]))
break;
// make sure the lines don't do shitty things outside
// bounds
if (!mViewPortHandler.isInBoundsLeft(mLineBuffer[2])
|| (!mViewPortHandler.isInBoundsTop(mLineBuffer[1]) && !mViewPortHandler
.isInBoundsBottom(mLineBuffer[3])))
continue;
// get the color that is set for this line-segment
mRenderPaint.setColor(dataSet.getColor(j));
canvas.drawLines(mLineBuffer, 0, pointsPerEntryPair * 2, mRenderPaint);
}
} else { // only one color per dataset
if (mLineBuffer.length < Math.max((entryCount) * pointsPerEntryPair, pointsPerEntryPair) * 2)
mLineBuffer = new float[Math.max((entryCount) * pointsPerEntryPair, pointsPerEntryPair) * 4];
Entry e1, e2;
e1 = dataSet.getEntryForIndex(mXBounds.min);
if (e1 != null) {
int j = 0;
for (int x = mXBounds.min; x <= mXBounds.range + mXBounds.min; x++) {
e1 = dataSet.getEntryForIndex(x == 0 ? 0 : (x - 1));
e2 = dataSet.getEntryForIndex(x);
//实现这个效果重点就是这行代码
if (e1.getY()==0||e2.getY()==0) continue;
if (e1 == null || e2 == null) continue;
mLineBuffer[j++] = e1.getX();
mLineBuffer[j++] = e1.getY() * phaseY;
mLineBuffer[j++] = e2.getX();
mLineBuffer[j++] = e2.getY() * phaseY;
}
if (j > 0) {
trans.pointValuesToPixel(mLineBuffer);
final int size = Math.max((mXBounds.range + 1) * pointsPerEntryPair, pointsPerEntryPair) * 2;
mRenderPaint.setColor(dataSet.getColor());
canvas.drawLines(mLineBuffer, 0, size, mRenderPaint);
}
}
}
mRenderPaint.setPathEffect(null);
}