2017-04-11 48 views
2

enter image description here的Android - 填寫使用MPAndroidChart

我使用setFillFormatter兩條線之間的顏色,但它沒有幫助我,並setfillColor()穿過第二線(黑色),因爲沒有辦法阻止第一行(黃色)在第二行的Y值。 我想實現這樣的事情:

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值?我同時看到dataSetdataProvider爲getFillLinePosition的每個調用返回固定值。

+1

我不認爲你可以做到這一點用在圖書館所提供的方法。您可能必須編寫自定義渲染器來執行此操作。看看'LineChartRenderer' –

回答

3

感謝David Rawson指着我朝着LineChartRenderer。我能夠在兩行之間着色區域。

我們需要做兩個重大的改變。

  1. 執行自定義FillFormator以返回另一行的數據集。

    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; 
    }} 
    
  2. 實現自定義LineChartRenderer繪製和填充封閉路徑。

    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(); 
    }} 
    
  3. 在活動

    路過另一LineDataSet作爲參數,最終將MyFillFormatterLineDataSet之一。

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

enter image description here