2015-05-11 9 views
7

Sto utilizzando una classe MarkerView per mostrare i panorami nel grafico. Il layout markerview che ho creato contiene due textview, uno sotto l'altro.MarkerView esce dal grafico per l'ultimo punto del grafico

Il problema che sto affrontando è che il markerview per l'ultimo punto sul grafico è la metà all'interno del grafico e metà all'esterno del grafico. Le due immagini sottostanti stato chiaramente il problema:

La prima immagine mostra una markerview per un punto nel centro del grafico che mostra senza alcun problema:

enter image description here

La seconda immagine, come mostrato sotto , mostra il markerview per l'ultimo punto del grafico, che è la metà all'interno del grafico.

enter image description here

Come faccio ad avere questo markerview per regolare in modo che si vede all'interno del grafico.

Il wiki non specifica alcuna personalizzazione per il markerview. Ci sono altre personalizzazioni?

Inoltre, in caso di un grafico a linee multiple, se si fa clic solo su uno dei punti di linea, l'analisi dei contrassegni non presenta problemi. Ma se clicco per il markerview su qualsiasi punto sull'altra linea, l'applicazione fallisce. Qualche idea del perché accada questo.

Il codice per la classe markerview è il seguente:

public class TooltipView extends MarkerView { 

private BaseGraphMetadata mBaseGraphMetadata; 

private TextView mTooltipDate, mTooltipValue; 

public TooltipView(Context context, int layoutResource, BaseGraphMetadata baseGraphMetadata) { 
    super(context, layoutResource); 
    mTooltipDate = (TextView)findViewById(R.id.tooltip_date); 
    mTooltipValue = (TextView)findViewById(R.id.tooltip_value); 
    mBaseGraphMetadata = baseGraphMetadata; 
} 

@Override 
public void refreshContent(Entry entry, int i) { 
    List<DrillDownInfo> drillDownInfoList = (List<DrillDownInfo>) entry.getData(); 
    DrillDownInfo drillDownInfo = drillDownInfoList.get(i); 
    Map<String, String> group = drillDownInfo.getGroupByNameVsGroupByValue(); 
    Iterator iterator = group.entrySet().iterator(); 
    while (iterator.hasNext()) { 
     Map.Entry pair = (Map.Entry)iterator.next(); 
     if(pair.getKey()!=null && pair.getValue()!=null) { 
      String key = (String) pair.getKey(); 
      key = key.toUpperCase(); 
      Double value = Double.parseDouble((String) pair.getValue()); 
      String formattedValue = mBaseGraphMetadata.getDataFormatter().getFormattedValue(value); 
      mTooltipDate.setText(key + " : " + formattedValue); 
     } 
     iterator.remove(); 
    } 
    mTooltipValue.setText(String.valueOf("VALUE : "+entry.getVal())); 
} 

@Override 
public int getXOffset() { 
    return -(getWidth()/2); 
} 

@Override 
public int getYOffset() { 
    return -getHeight(); 
} 
} 

risposta

2

Basta mettere un po 'di logica nel vostro MarkerView. Se l'ultimo valore è evidenziato, il metodo getXOffset() dovrebbe restituire qualcosa di diverso.

Ciò che viene restituito, viene calcolato nel metodo refreshContent(...).

Inoltre, è possibile dare un'occhiata ai seguenti proprietà XML:

android:clipChildren="false" 
android:clipToPadding="false" 

che deve essere impostato per il grafico-view.

+0

Le due proprietà XML non aiutano. –

+0

Inoltre, quando clicco su un punto del grafico ottengo due linee che si intersecano nel punto cliccato. Si prega di fare riferimento alle immagini nella domanda. Come rimuovo quelle linee? –

+0

Sono chiamate linee di indicatori di evidenziazione, dare un'occhiata a [la documentazione] (https://github.com/PhilJay/MPAndroidChart/wiki/Interaction-with-the-Chart). –

4

Dal

android:clipChildren="false" 
android:clipToPadding="false" 

non ha funzionato per me, ho finito per creare 3 drawable differenti. A seconda dell'indice di entrata, io uso l'uno o l'altro. E, per mantenere centrata la freccia, XOffset cambia di conseguenza. Credo che sia una soluzione molto specifico, ma l'idea è esportabile

@Override 
    public void refreshContent(Entry e, int dataSetIndex) { 
    if (e.getXIndex() < 4) { 
     xOffsetMultiplier = 3.2f; 
     tvContent.setBackgroundResource(R.drawable.stats_marker_left_side); 
    } else if (e.getXIndex() > mTimestamps.length - 6) { 
     //timestamps is an array containing xValues timestamps 
     xOffsetMultiplier = 1.12f; 
     tvContent.setBackgroundResource(R.drawable.stats_marker_right_side); 
    } else { 
     xOffsetMultiplier = 2; 
     tvContent.setBackgroundResource(R.drawable.stats_marker); 
    } 

    tvContent.setText(createMarkerViewText(e)); 
    } 

    @Override 
    public int getXOffset() { 
    // this will center the marker-view horizontally 
    return (int) -(getWidth()/xOffsetMultiplier); 
    } 

Questo è il risultato

enter image description here enter image description here enter image description here

I drawable vengono copiati da campioni MPAndroidChart, trasformati in 9.patch e adattato alle mie esigenze.Metterli dentro drawable-nodpi

enter image description here enter image description here enter image description here

+0

Che cos'è 9.patch? –

+0

Usa Goole ... http://developer.android.com/tools/help/draw9patch.html – Maragues

+0

Ci sono strumenti per creare 9 immagini patch. Ma come funzionano? Inoltre, come faccio a convertire un'immagine normale in 9 patch? –

5

un po 'tardi, ma qui è la mia semplice soluzione per questo problema.

È necessario Override il metodo draw della vostra dogana MarkerView.

Devi solo controllare che posx non sta per chiudere da uno dei tuoi bordi (da 0 per il lato destro alla posizione a seconda delle dimensioni dello schermo, ad esempio 300 per il mio schermo).

Un semplice esempio:

@Override 
     public void draw(Canvas canvas, float posx, float posy) 
     { 
      // take offsets into consideration 
      posx += getXOffset(); 
      posy=0; 

      // AVOID OFFSCREEN 
      if(posx<45) 
       posx=45; 
      if(posx>265) 
       posx=265; 

      // translate to the correct position and draw 
      canvas.translate(posx, posy); 
      draw(canvas); 
      canvas.translate(-posx, -posy); 
     } 

Qui, posso controllare la mia posizione x, mentre assicurando che il marcatore rimanere sempre sulla parte superiore del grafico (Se non lo vogliono, uso p osy += getYOffset(); invece)

+0

Grazie aiuta. – rolyanos

2

Ho affrontato lo stesso problema. Ho rettificato che facendo particolare il metodo di seguito la mia customMarkerview classe:

@Override 
public int getXOffset(float xpos) { 

    // this will center the marker-view horizontally 
    int min_offset = 50; 
    if (xpos < min_offset) 
     return 0; 

    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE); 
    DisplayMetrics metrics = new DisplayMetrics(); 
    wm.getDefaultDisplay().getMetrics(metrics); 
    //For right hand side 
    if (metrics.widthPixels - xpos < min_offset) 
     return -getWidth(); 
      //For left hand side 
    else if (metrics.widthPixels - xpos < 0) 
     return -getWidth(); 
    return -(getWidth()/2); 
} 
3

ho trovato una semplice soluzione a questo problema. È necessario impostare tabella nella visualizzazione indicatore personalizzato come di seguito:

setChartView(chart); 

..e l'override del metodo draw come di seguito:

@Override 
public void draw(Canvas canvas, float posX, float posY) { 
    super.draw(canvas, posX, posY); 
    getOffsetForDrawingAtPoint(posX, posY); 
} 
0

La migliore risposta sta nella libreria stessa. Controlla il metodo getOffsetForDrawingAtPoint() da MarkerView. Ha definito il modo perfetto per calcolare l'offset. Usare la logica che da lì e utilizzare in onDraw il metodo del vostro indicatore personalizzato come segue:

@Override 
    public void draw(Canvas canvas, float posX, float posY) { 
     // take offsets into consideration 
     int lineChartWidth = 0; 
     float offsetX = getOffset().getX(); 
     posY=0;//fix at top 
     float width = getWidth(); 

     if(lineChart != null) { 
      lineChartWidth = lineChart.getWidth(); 
     } 
     if(posX + offsetX < 0) { 
      offsetX = - posX; 
     } else if(posX + width + offsetX > lineChartWidth) { 
      offsetX = lineChartWidth - posX - width; 
     } 
     posX += offsetX; 
     // translate to the correct position and draw 
     canvas.translate(posX, posY); 
     draw(canvas); 
     canvas.translate(-posX, -posY); 
    } 
+0

Non è necessario sovrascrivere il disegno, se si chiama setChartView (grafico), quindi getOffsetForDrawingAtPoint() calcolerà l'offset correttamente –

Problemi correlati