我使用了Amit的
被接受的回答,但是修改了他的
MyLineLegendRenderer
,以便您还可以在两个
水平贝塞尔线之间填充 - 例如,如果您正在使用
myDataSet.setMode(LineDataSet.Mode.HORIZONTAL_BEZIER);
我还稍微整理了一下代码 - 比如添加了注释、删除了冗余的代码等等。
因此,这是我替换 Amit 的
MyLineLegendRenderer
类的代码:
import android.graphics.Canvas;
import android.graphics.Path;
import android.graphics.drawable.Drawable;
import com.github.mikephil.charting.animation.ChartAnimator;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
import com.github.mikephil.charting.renderer.LineChartRenderer;
import com.github.mikephil.charting.utils.Transformer;
import com.github.mikephil.charting.utils.ViewPortHandler;
import java.util.List;
public class MyLineLegendRenderer extends LineChartRenderer {
MyLineLegendRenderer(LineDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
}
@Override
protected void drawLinearFill(Canvas c, ILineDataSet dataSet, Transformer trans, XBounds bounds) {
final Path filled = mGenerateFilledPathBuffer;
final int startingIndex = bounds.min;
final int endingIndex = bounds.range + bounds.min;
final int indexInterval = 128;
int currentStartIndex;
int currentEndIndex;
int iterations = 0;
do {
currentStartIndex = startingIndex + (iterations * indexInterval);
currentEndIndex = currentStartIndex + indexInterval;
currentEndIndex = currentEndIndex > endingIndex ? endingIndex : currentEndIndex;
if (currentStartIndex <= currentEndIndex) {
generateFilledPath(dataSet, currentStartIndex, currentEndIndex, filled);
trans.pathValueToPixel(filled);
final Drawable drawable = dataSet.getFillDrawable();
if (drawable != null) {
drawFilledPath(c, filled, drawable);
}
else {
drawFilledPath(c, filled, dataSet.getFillColor(), dataSet.getFillAlpha());
}
}
iterations++;
} while (currentStartIndex <= currentEndIndex);
}
@Override
protected void drawCubicFill(Canvas c, ILineDataSet dataSet, Path spline, Transformer trans, XBounds bounds) {
final float phaseY = mAnimator.getPhaseY();
final List<Entry> boundaryEntries = ((MyFillFormatter)dataSet.getFillFormatter()).getFillLineBoundary();
Entry boundaryEntry = boundaryEntries.get(bounds.min + bounds.range);
spline.lineTo(boundaryEntry.getX(), boundaryEntry.getY() * phaseY);
Entry prev = dataSet.getEntryForIndex(bounds.min + bounds.range);
Entry cur = prev;
for (int x = bounds.min + bounds.range; x >= bounds.min; x--) {
prev = cur;
cur = boundaryEntries.get(x);
final float cpx = (prev.getX()) + (cur.getX() - prev.getX()) / 2.0f;
spline.cubicTo(
cpx, prev.getY() * phaseY,
cpx, cur.getY() * phaseY,
cur.getX(), cur.getY() * phaseY);
}
spline.close();
trans.pathValueToPixel(spline);
final Drawable drawable = dataSet.getFillDrawable();
if (drawable != null) {
drawFilledPath(c, spline, drawable);
}
else {
drawFilledPath(c, spline, dataSet.getFillColor(), dataSet.getFillAlpha());
}
}
private void generateFilledPath(final ILineDataSet dataSet, final int startIndex, final int endIndex, final Path outputPath) {
final float phaseY = mAnimator.getPhaseY();
final Path filled = outputPath;
filled.reset();
final List<Entry> boundaryEntries = ((MyFillFormatter)dataSet.getFillFormatter()).getFillLineBoundary();
final Entry entry = dataSet.getEntryForIndex(startIndex);
final Entry boundaryEntry = boundaryEntries.get(startIndex);
filled.moveTo(entry.getX(), boundaryEntry.getY() * phaseY);
filled.lineTo(entry.getX(), entry.getY() * phaseY);
Entry currentEntry;
for (int x = startIndex + 1; x <= endIndex; x++) {
currentEntry = dataSet.getEntryForIndex(x);
filled.lineTo(currentEntry.getX(), currentEntry.getY() * phaseY);
}
Entry boundaryEntry1;
for (int x = endIndex; x > startIndex; x--) {
boundaryEntry1 = boundaryEntries.get(x);
filled.lineTo(boundaryEntry1.getX(), boundaryEntry1.getY() * phaseY);
}
filled.close();
}
}
您应该将此类与Amit的答案中的其他代码一起使用。
LineChartRenderer
。 - David Rawson