2012-04-12 8 views
6

Androidplot(androidplot.com)のウェブサイト/フォーラムがダウンしているので、ここでこの質問をしてみます。Androidplotの最適化

私はマルチタッチズームとスクロールしています。 http://mlepicki.com/2012/03/androidplot-multitouch-zoom-scroll/と同様のコードですが、代わりに棒グラフがあります。しかし、100データポイントでは、それは顕著な遅れを有する。 10本のバーが表示されています。すべてのバーの描画/計算/等のように聞こえます。

これをどのように最適化することができますか?

私はAndroid 2.1をサポートしたいので、ハードウェアレンダリングは使用できません。ライブラリはそれをサポートしていません(壊れます)。

+1

簡単なFYI - フォーラムがバックアップされています。 – 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."); 
        } 
       } 
      } 
     } 
    } 
}