2015-07-03 169 views
9

我正在使用MPAndroid圖表庫在我的Android應用程序中繪製折線圖。圖中的狀態是這樣的: MPAndroidChart - Line ChartMPAndroidChart LineChart自定義高亮可繪製

我想改變這樣的:

Line Chart

所以我想改變MPAnroid折線圖的點,TS稱爲「圓孔」在庫中。我想切換這個洞來繪製。有一種方法可以做到這一點?

的圓孔改變代碼是在這裏:

LineDataSet set1 = new LineDataSet(yVals, "DataSet 1"); 
set1.setDrawCircleHole(true); 
set1.setCircleColor(Color.BLACK); 

庫引用是在這裏:MPAndroidChart

+0

你是什麼意思「關掉這個洞可繪」是什麼意思?你想自己繪製而不是CircleHole嗎? – Paamand

+0

您是否找到了更改可突出顯示的解決方案? – Massimo

+0

@Massimo請看我最新的答案,其中包含示例代碼 –

回答

6

自從3.0版本,你可以提供將在上選擇一個給定的點來顯示自己的自定義圖像圖表。下面的說明是按照the wiki

總之,你現在可以使用名爲MarkerImage類:

MarkerImage myMarkerImage = new MarkerImage(this, R.drawable.my_drawable); 

然後:

myChart.setMarker(myMarkerImage); 

要調整圖像的位置,你可以調用:

setOffset(float x, float y); 

如果你不想使用MarkerView,您可能必須創建自己的LineChartRenderer的子類,並添加邏輯以繪製自定義高光可繪製。

這裏是概念的一個非常基本的證明:

import android.graphics.Bitmap; 
import android.graphics.Canvas; 

import com.github.mikephil.charting.animation.ChartAnimator; 
import com.github.mikephil.charting.charts.LineChart; 
import com.github.mikephil.charting.data.Entry; 
import com.github.mikephil.charting.data.LineData; 
import com.github.mikephil.charting.highlight.Highlight; 
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; 

/** 
* Created by David on 3/01/2017. 
*/ 

public class ImageLineChartRenderer extends LineChartRenderer { 

    private final LineChart lineChart; 
    private final Bitmap image; 

    public ImageLineChartRenderer(LineChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler, Bitmap image) { 
     super(chart, animator, viewPortHandler); 
     this.lineChart = chart; 
     this.image = image; 
    } 

    @Override 
    public void drawExtras(Canvas c) { 
     super.drawExtras(c); 

     Highlight[] highlighted = lineChart.getHighlighted(); 
     if (highlighted == null) return; 

     float phaseY = mAnimator.getPhaseY(); 

     float[] imageBuffer = new float[2]; 
     imageBuffer[0] = 0; 
     imageBuffer[1] = 0; 
     LineData lineData = mChart.getLineData(); 
     List<ILineDataSet> dataSets = mChart.getLineData().getDataSets(); 

     Bitmap[] scaledBitmaps = new Bitmap[dataSets.size()]; 
     float[] scaledBitmapOffsets = new float[dataSets.size()]; 
     for (int i = 0; i < dataSets.size(); i++) { 
      float imageSize = dataSets.get(i).getCircleRadius() * 10; 
      scaledBitmapOffsets[i] = imageSize/2f; 
      scaledBitmaps[i] = scaleImage((int) imageSize); 
     } 

     for (Highlight high : highlighted) { 
      int dataSetIndex = high.getDataSetIndex(); 
      ILineDataSet set = lineData.getDataSetByIndex(dataSetIndex); 
      Transformer trans = lineChart.getTransformer(set.getAxisDependency()); 

      if (set == null || !set.isHighlightEnabled()) 
       continue; 

      Entry e = set.getEntryForXValue(high.getX(), high.getY()); 

      if (!isInBoundsX(e, set)) 
       continue; 

      imageBuffer[0] = e.getX(); 
      imageBuffer[1] = e.getY() * phaseY; 
      trans.pointValuesToPixel(imageBuffer); 

      c.drawBitmap(scaledBitmaps[dataSetIndex], 
        imageBuffer[0] - scaledBitmapOffsets[dataSetIndex], 
        imageBuffer[1] - scaledBitmapOffsets[dataSetIndex], 
        mRenderPaint); 
     } 
    } 

    private Bitmap scaleImage(int radius) { 
     return Bitmap.createScaledBitmap(image, radius, radius, false); 
    } 
} 

消耗它是這樣的:

Bitmap starBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.star); 
mChart.setRenderer(new ImageLineChartRenderer(mChart, mChart.getAnimator(), mChart.getViewPortHandler(), starBitmap)); 

說明:drawExtrasLineChartRenderer繪製圓。我們仍然想要這些,所以在我們的drawExtras覆蓋,我們稱之爲超級第一。然後我們爲每個DataSet生成縮放的位圖(DataSet可能有不同的圓半徑)。我們將位圖縮放到任意大小(圓圈半徑的10倍)。然後,我們遍歷通過渲染器的LineChart字段暴露的Highlights,並繪製相應的位圖。

下面是截圖 - 你可以看到「明星」圖而不是圓上突出顯示指數:

a line chart with a star instead of a circle at the highlighted point

+1

謝謝@David Rawson,你救了我吧! myChart.setMarker(myMarkerImage);它不適合我,它會覆蓋我的MarkerView,我嘗試你的概念的基本證明,它的工作原理,儘管對我來說很難。謝謝。 –

+1

有關如何編寫自定義渲染器的更多信息,請參閱以下問題:http:// stackoverflow。com/q/43443787/5241933 –

+0

過了很久,你還是分享這些信息,謝謝。 –