android - 优化Androidplot

标签 android graph androidplot

似乎 Androidplot (androidplot.com) 网站/论坛已关闭,所以我会尝试在这里问这个问题。

我有多点触控缩放和滚动。与 http://mlepicki.com/2012/03/androidplot-multitouch-zoom-scroll/ 类似的代码除了我有一个条形图。但是,对于 100 个数据点,它有明显的滞后。即使有 10 个酒吧也只是显示。听起来像它的绘图/计算/等等所有条形图。

知道如何优化它吗?

我无法使用硬件渲染,因为我想支持 Android 2.1,但库不支持它(它会损坏)。

最佳答案

我制作了一个自定义渲染器来解决我的滞后问题。似乎流畅了许多。此代码基于版本 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.");
                    }
                }
            }
        }
    }
}

关于android - 优化Androidplot,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10132885/

相关文章:

java - 错误 : Cannot find symbol class view

Android 4.3 crop gallery resultCode 取消

android - 推出新应用版本时 list 权限更改

graph - 如何在具有一组起点和目标点的图形中找到最长的路径?

algorithm - 探索图中的每个节点

AndroidPlot 不可见标记

android - 如何在 AndroidPlot 中删除图表周围的所有空间?

javascript - 如何确定音频文件扩展名可能是什么(Chrome,Android)?

testing - 路径覆盖中不可行的路径

android图表库——androidplot onclick问题