如图所示
本文主要提供思路,当遇到此类问题后,应该怎么去想,毕竟总有需求跟框架不一样,甚至违背。
线都是有点构成的,如果不绘制如图所示的x=3点及其与x=2和x=4的线。所以我们思路应该有以下几点
1.在不需要绘制的Entry里面丢入不绘制的标记
2.找到LineDataSet使用的地方Drawline,在满足某条件1下的Entry(x,y)不去绘制
*3.方便不影响原框架效果 可以再加一个字段为true时候才启用这种模式
Entry有很多构造方法我这里直接采用Y = Float.NaN 作为标记
模拟数据如下,我们假设i==3是我们不想绘制的点
ArrayList<Entry> values = new ArrayList<Entry>();
for (int i = 0; i < count; i++) {
float val = (float) (Math.random() * range) + 3;
if (i == 3) {
values.add(new Entry(i, Float.NaN));
} else {
values.add(new Entry(i, val));
}
}
LineDataSet set1 = new LineDataSet(values, "DataSet 1");
然后我们全局搜索LineDataSet 或者drawLine,再找到两个Entry或者(x,y)同时使用的代码区域
LineChartRenderer中的drawLinear就是我们需要的
/**
* Draws a normal line.
*
* @param c
* @param dataSet
*/
protected void drawLinear(Canvas c, ILineDataSet dataSet) {
int entryCount = dataSet.getEntryCount();
final boolean isDrawSteppedEnabled = dataSet.isDrawSteppedEnabled();
final int pointsPerEntryPair = isDrawSteppedEnabled ? 4 : 2;
Transformer trans = mChart.getTransformer(dataSet.getAxisDependency());
float phaseY = mAnimator.getPhaseY();
mRenderPaint.setStyle(Paint.Style.STROKE);
Canvas canvas = null;
// if the data-set is dashed, draw on bitmap-canvas
if (dataSet.isDashedLineEnabled()) {
canvas = mBitmapCanvas;
} else {
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;
if (isDrawSteppedEnabled) {
mLineBuffer[2] = e.getX();
mLineBuffer[3] = mLineBuffer[1];
mLineBuffer[4] = mLineBuffer[2];
mLineBuffer[5] = mLineBuffer[3];
mLineBuffer[6] = e.getX();
mLineBuffer[7] = e.getY() * phaseY;
} else {
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 == null || e2 == null) continue;
mLineBuffer[j++] = e1.getX();
mLineBuffer[j++] = e1.getY() * phaseY;
if (isDrawSteppedEnabled) {
mLineBuffer[j++] = e2.getX();
mLineBuffer[j++] = e1.getY() * phaseY;
mLineBuffer[j++] = e2.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);
ok我们根据分析的逻辑快速的找到有两个entry的地方,自然是得出画线的地方 我们看到了
if (e1 == null || e2 == null) continue;
当某个entry为空的时候继续下面,显然我们需要的和这个类似所以在这个下面加上我们需要的
if (Float.isNaN(e1.getY())||Float.isNaN(e2.getY()) {
continue;
}
编译下就得到了结果,那照这个逻辑entry直接传空可以不,并不行,因为entry会有很多地方使用,万一框架作者哪里忘记判断空了岂不是就报异常了,其他框架如果不是自带这个功能,也可以类似的去操作,我写这篇文章主要是分享思考到实现的过程