2012-04-12 12 views
6

Parece que el sitio web/foros de Android plot (androidplot.com) no funcionan, así que intentaré hacer esta pregunta aquí.Optimizar Androidplot

Tengo zoom táctil y desplazamiento. Código similar a http://mlepicki.com/2012/03/androidplot-multitouch-zoom-scroll/ excepto que tengo un gráfico de barras en su lugar. Sin embargo, con 100 puntos de datos, tiene un retraso notable. Incluso con 10 barras solo están mostrando. Suena como su dibujo/cálculo/etc. todas las barras.

¿Alguna idea de cómo podría optimizar esto?

No puedo usar la representación de hardware porque quiero admitir Android 2.1 y la biblioteca no lo admite (se rompe).

+1

Solo un rápido FYI - los foros son una copia de seguridad. – Nick

+0

Sí, lo sé, gracias :) – Zammbi

Respuesta

1

BarRenderer se optimizó un poco en Androidplot 1.4.0 por lo que un intérprete personalizado ya no debería ser necesario.

+0

Genial para escuchar. Tendré que intentarlo. – Zammbi

6

Hice un procesador personalizado para resolver mis problemas de retraso. Parece ser mucho más suave. Este código está basado en la versión 0.5. No tengo idea si funciona en v0.51.

import android.graphics.*; 
import com.androidplot.exception.PlotRenderException; 
import com.androidplot.series.XYSeries; 
import com.androidplot.util.ValPixConverter; 
import com.androidplot.xy.BarFormatter; 
import com.androidplot.xy.XYPlot; 
import com.androidplot.xy.XYSeriesRenderer; 

import java.util.List; 
import java.util.Map; 
import java.util.TreeMap; 

/** 
* Renders a point as a Bar 
*/ 
public class OptimisedBarRenderer extends XYSeriesRenderer<BarFormatter> { 

    private BarWidthStyle style = BarWidthStyle.FIXED_WIDTH; 
    private float barWidth = 5; 

    public OptimisedBarRenderer(XYPlot plot) { 
     super(plot); 
    } 

    /** 
    * Sets the width of the bars draw. 
    * @param barWidth 
    */ 
    public void setBarWidth(float barWidth) { 
     this.barWidth = barWidth; 
    } 

    private final TreeMap<Number, XYSeries> tempSeriesMap = new TreeMap<Number, XYSeries>(); 

    @Override 
    public void onRender(Canvas canvas, RectF plotArea) throws PlotRenderException { 
     int longest = getLongestSeries(); 
     if(longest == 0) { 
      return; // no data, nothing to do. 
     } 
     tempSeriesMap.clear(); 

     for(int i = 0; i < longest; i++) { 
      tempSeriesMap.clear(); 
      List<XYSeries> seriesList = getPlot().getSeriesListForRenderer(this.getClass()); 
      for(XYSeries series : seriesList) { 
       if(i < series.size()) { 
        tempSeriesMap.put(series.getY(i), series); 
       } 
      } 
      drawBars(canvas, plotArea, tempSeriesMap, i); 
     } 
    } 

    @Override 
    public void doDrawLegendIcon(Canvas canvas, RectF rect, BarFormatter formatter) { 
     canvas.drawRect(rect, formatter.getFillPaint()); 
     canvas.drawRect(rect, formatter.getBorderPaint()); 
    } 

    private int getLongestSeries() { 
     int longest = 0; 
     List<XYSeries> seriesList = getPlot().getSeriesListForRenderer(this.getClass()); 

     if(seriesList == null) 
      return 0; 

     for(XYSeries series :seriesList) { 
      int seriesSize = series.size(); 
      if(seriesSize > longest) { 
       longest = seriesSize; 
      } 
     } 
     return longest; 
    } 

    private void drawBars(Canvas canvas, RectF plotArea, TreeMap<Number, XYSeries> seriesMap, int x) { 
//  Paint p = new Paint(); 
//  p.setColor(Color.RED); 

     Object[] oa = seriesMap.entrySet().toArray(); 
     Map.Entry<Number, XYSeries> entry; 
     Number yVal = null; 
     Number xVal = null; 

     float halfWidth = barWidth * 0.5f; 

     for(int i = oa.length-1; i >= 0; i--) { 
      entry = (Map.Entry<Number, XYSeries>) oa[i]; 
      XYSeries tempEntry = entry.getValue(); 

      if(tempEntry != null) { 
       yVal = tempEntry.getY(x); 
       xVal = tempEntry.getX(x); 

       if (yVal != null && xVal != null) { // make sure there's a real value to draw 
        switch (style) { 
         case FIXED_WIDTH: 
          float pixX = ValPixConverter.valToPix(xVal.doubleValue(), getPlot().getCalculatedMinX().doubleValue(), getPlot().getCalculatedMaxX().doubleValue(), plotArea.width(), false) + plotArea.left; 

          float left = pixX - halfWidth; 
          float right = pixX + halfWidth; 

          boolean offScreen = left > plotArea.right || right < plotArea.left; 

          if(!offScreen){ 
           float pixY = ValPixConverter.valToPix(yVal.doubleValue(), getPlot().getCalculatedMinY().doubleValue(), getPlot().getCalculatedMaxY().doubleValue(), plotArea.height(), true) + plotArea.top; 

           BarFormatter formatter = getFormatter(tempEntry); 
           if(Math.abs (left - right) > 1f){//Don't draw as it will be hidden anyway. 
            canvas.drawRect(left, pixY, right, plotArea.bottom, formatter.getFillPaint()); 
           } 
           canvas.drawRect(left, pixY, right, plotArea.bottom, formatter.getBorderPaint()); 

          } 
          break; 
         default: 
          throw new UnsupportedOperationException("Not yet implemented."); 
        } 
       } 
      } 
     } 
    } 
}