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 { 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 tempSeriesMap = new TreeMap(); @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 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 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 seriesMap, int x) { // Paint p = new Paint(); // p.setColor(Color.RED); Object[] oa = seriesMap.entrySet().toArray(); Map.Entry entry; Number yVal = null; Number xVal = null; float halfWidth = barWidth * 0.5f; for(int i = oa.length-1; i >= 0; i--) { entry = (Map.Entry) 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."); } } } } } }