2012-04-12 1 views
6

Androidplot (androidplot.com) 웹 사이트/포럼이 다운되어 있으므로 여기에서이 질문을 시도해 보겠습니다.Androidplot 최적화

나는 멀티 터치 줌 및 스크롤 기능이 있습니다. http://mlepicki.com/2012/03/androidplot-multitouch-zoom-scroll/과 비슷한 코드는 대신 막대 그래프가 있습니다. 그러나 100 개의 데이터 포인트에서 눈에 띄는 지연이 있습니다. 10 개의 막대가 표시되고 있습니다. 그 그림/계산/등 모든 막대와 같은 소리.

내가 어떻게 최적화 할 수 있는지에 대한 아이디어가 있습니까?

Android 2.1을 지원하고 라이브러리가 지원하지 않기 때문에 하드웨어 렌더링을 사용할 수 없습니다 (중단됩니다).

+1

간단히 요약하면 포럼이 백업됩니다. – Nick

+0

그래, 고마워. :) – Zammbi

답변

1

BarRenderer 때문에 사용자 정의 렌더러가 더 이상 필요 없을 것 Androidplot 1.4.0에서 상당히 최적화되었다.

+0

듣기 좋네. 시도 해봐야 할 것입니다. – Zammbi

6

난 후행 문제를 해결하기 위해 맞춤 렌더러를 만들었습니다. 훨씬 더 부드럽게 보입니다. 이 코드는 버전 0.5를 기반으로합니다. 그것은 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."); 
        } 
       } 
      } 
     } 
    } 
}