I am able to achieve this by implementing a custom FillFormatter and a LineChartRenderer. Hope this solution helps someone.
public class MyFillFormatter implements IFillFormatter {
private ILineDataSet boundaryDataSet;
public MyFillFormatter() {
this(null);
}
//Pass the dataset of other line in the Constructor
public MyFillFormatter(ILineDataSet boundaryDataSet) {
this.boundaryDataSet = boundaryDataSet;
}
@Override
public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
return 0;
}
//Define a new method which is used in the LineChartRenderer
public List<Entry> getFillLineBoundary() {
if(boundaryDataSet != null) {
return ((LineDataSet) boundaryDataSet).getValues();
}
return null;
}}
public class MyLineLegendRenderer extends LineChartRenderer {
public MyLineLegendRenderer(LineDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
}
//This method is same as it's parent implementation
@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 = 0;
int currentEndIndex = indexInterval;
int iterations = 0;
// Doing this iteratively in order to avoid OutOfMemory errors that can happen on large bounds sets.
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);
}
//This is where we define the area to be filled.
private void generateFilledPath(final ILineDataSet dataSet, final int startIndex, final int endIndex, final Path outputPath) {
//Call the custom method to retrieve the dataset for other line
final List<Entry> boundaryEntry = ((MyFillFormatter)dataSet.getFillFormatter()).getFillLineBoundary();
final float phaseY = mAnimator.getPhaseY();
final Path filled = outputPath;
filled.reset();
final Entry entry = dataSet.getEntryForIndex(startIndex);
filled.moveTo(entry.getX(), boundaryEntry.get(0).getY());
filled.lineTo(entry.getX(), entry.getY() * phaseY);
// create a new path
Entry currentEntry = null;
Entry previousEntry = null;
for (int x = startIndex + 1; x <= endIndex; x++) {
currentEntry = dataSet.getEntryForIndex(x);
filled.lineTo(currentEntry.getX(), currentEntry.getY() * phaseY);
}
// close up
if (currentEntry != null && previousEntry!= null) {
filled.lineTo(currentEntry.getX(), previousEntry.getY());
}
//Draw the path towards the other line
for (int x = endIndex ; x > startIndex; x--) {
previousEntry = boundaryEntry.get(x);
filled.lineTo(previousEntry.getX(), previousEntry.getY() * phaseY);
}
filled.close();
}}
lineDataSet2.setFillFormatter(new MyFillFormatter(LineDataSet1));
mChart.setRenderer(new MyLineLegendRenderer(mChart, mChart.getAnimator(), mChart.getViewPortHandler()));
I am able to achieve this by implementing a custom FillFormatter and a LineChartRenderer. Hope this solution helps someone.
FillFormatorwhich return the dataset of other line.LineChartRendererto draw and fill the enclosed path.3.At the end from the activity
Set the MyFillFormatter to one of the LineDataSet passing other LineDataSet as argument.