2012-04-12 39 views
6

似乎Androidplot(androidplot.com)網站/論壇已關閉,因此我會嘗試在此處詢問此問題。優化Androidplot

我有多點觸摸縮放和滾動。與http://mlepicki.com/2012/03/androidplot-multitouch-zoom-scroll/類似的代碼除了我有一個條形圖代替。然而,有100個數據點它有明顯的滯後。即使有10個酒吧只是顯示。聽起來像它的繪圖/計算/等所有酒吧。

關於如何優化這個的任何想法?

我不能使用硬件渲染,因爲我想支持Android 2.1並且庫不支持它(它會中斷)。

+1

只是一個快速的FYI - 論壇已備份。 – Nick 2012-09-19 22:30:43

+0

是的,我知道,謝謝:) – Zammbi 2012-09-21 03:17:23

回答

1

BarRenderer進行了優化,在Androidplot 1.4.0頗有幾分這樣一個自定義渲染不再是必要的。

+0

很好聽。將不得不嘗試一下。 – Zammbi 2017-02-15 21:24:41

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