2015-07-03 6 views
9

Ich benutze MPAndroid Chart-Bibliothek, um Liniendiagramm in meiner Android App zu zeichnen. Der Status der Graph ist wie: MPAndroidChart - Line ChartMPAndroidChart LineChart benutzerdefinierte Hervorhebung Zeichenerklärung

ich es ändern wollen, wie folgt aus:

Line Chart

Deshalb möchte ich MPAnroid Liniendiagramm die Punkte ändern, ts "Circle Hole" in der Bibliothek genannt. Ich möchte dieses Loch auf Drawable umstellen. Es gibt einen Weg, wie ich das tun kann?

Der Änderungscode Kreis Loch ist hier:

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

Bibliothek Referenz hier: MPAndroidChart

+0

Was meinst du mit „dieses Loch wechseln drawable“? Möchtest du dein eigenes Zeichen anstelle des CircleHole? – Paamand

+0

Haben Sie eine Lösung gefunden, um das Highlight-Zeichen zu ändern? – Massimo

+0

@Massimo Bitte sehen Sie meine aktualisierte Antwort, die Beispielcode enthält –

Antwort

6

Seit der Version 3.0 können Sie Ihre eigenen Bild zur Verfügung stellen kann, die auf die Auswahl eines bestimmten Punkt auf der angezeigt wird Diagramm. Die folgenden Anweisungen sind pro the wiki

Zusammengefasst Sie nun die Klasse MarkerImage genannt verwenden können:

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

Dann:

myChart.setMarker(myMarkerImage); 

Um die Position des Bildes anpassen, können Sie anrufen :

setOffset(float x, float y); 

Wenn Sie nichtverwenden möchten, müssten Sie wahrscheinlich Ihre eigene Unterklasse von LineChartRenderer erstellen und Logik hinzufügen, um Ihre benutzerdefinierte Hervorhebung zeichnungsfähig zu zeichnen.

Dies ist ein sehr einfaches Proof of Concept:

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

es so Verbrauchen:

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

Erläuterung: drawExtras in LineChartRenderer die Kreise zieht. Wir wollen immer noch diese, also in unserem drawExtras Override nennen wir zuerst super. Dann erzeugen wir für jedes DataSet eine skalierte Bitmap (DataSets können unterschiedliche Kreisradien haben). Wir skalieren die Bitmaps auf eine beliebige Größe (10x der Kreisradius). Wir durchlaufen dann die Highlights, die über das LineChart-Feld unseres Renderers verfügbar sind, und zeichnen die entsprechende Bitmap. Hier

ist ein Screenshot - Sie können sehen, die ‚Stern‘ Bitmap anstelle des Kreises, auf dem markierten Index:

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

+1

Danke @David Rawson, Sie sparen mich! myChart.setMarker (myMarkerImage); es funktioniert nicht für mich, es wird mein MarkerView außer Kraft setzen, ich versuche es mit dem grundlegenden Konzept, es funktioniert, obwohl es für mich schwer ist. Vielen Dank. –

+1

Diese Frage enthält weitere Informationen zum Schreiben eines benutzerdefinierten Renderers: http: // stackoverflow.com/q/43443787/5241933 –

+0

Es war eine lange Zeit, teilen Sie immer noch die Informationen, danke. –