Android-使用MPAndroidChart在两行之间填充颜色 [英] Android - Fill the color between two lines using MPAndroidChart

查看:540
本文介绍了Android-使用MPAndroidChart在两行之间填充颜色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用setFillFormatter,但对我没有帮助, setfillColor()越过第二行(黑色),因为无法将第一行(黄色)停在第二行. 我想实现这样的东西:

I am using setFillFormatter, but it's not helping me and, setfillColor() crosses the second line(black) as there is no way to stop the first line(Yellow) at Y values of the second line. I want to implement something like this:

dataSet.setFillFormatter(new IFillFormatter() {

            @Override
            public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
                return //return Y value of the second line for current X of line being filled;
            }
        });

有没有办法针对第一行的每个X查找第二行的Y值?我看到 dataSet dataProvider 都为每次getFillLinePosition调用返回固定值.

Is there any way to find the Y value of the second line for each X of first line? I see both dataSet and dataProvider returns fixed values for each call of getFillLinePosition.

推荐答案

感谢David Rawson将我指向LineChartRenderer.我能够为两行之间的区域着色.

Thanks David Rawson for pointing me towards LineChartRenderer. I am able to color the area between two lines.

我们需要进行两项重大更改.

We need to make two major changes.

  1. 实施自定义FillFormator以返回另一行的数据集.

  1. Implement a custom FillFormator to return the dataset of another line.

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;
}}

  • 实施自定义LineChartRenderer来绘制并填充封闭的路径.

  • Implement a custom LineChartRenderer to draw and fill the enclosed path.

    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 implemntation
    @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();
    }}
    

  • 活动结束时

  • At the end of the activity

    MyFillFormatter设置为LineDataSet之一,并通过另一个LineDataSet作为参数.

    Set the MyFillFormatter to one of the LineDataSet passing another LineDataSet as argument.

    lineDataSet2.setFillFormatter(new MyFillFormatter(LineDataSet1));
    
    mChart.setRenderer(new MyLineLegendRenderer(mChart, mChart.getAnimator(), mChart.getViewPortHandler()));
    

  • 这篇关于Android-使用MPAndroidChart在两行之间填充颜色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆