X-Git-Url: https://git.gag.com/?a=blobdiff_plain;ds=sidebyside;f=android-libraries%2Fachartengine%2Fsrc%2Forg%2Fachartengine%2Fchart%2FBarChart.java;fp=android-libraries%2Fachartengine%2Fsrc%2Forg%2Fachartengine%2Fchart%2FBarChart.java;h=d5d0fb235d03f2a0dc19be9a0a543ae81a360a6d;hb=9349577cdfdff682b2aabd6daa24fdc3a7449b58;hp=0000000000000000000000000000000000000000;hpb=30ba0a882f0c061176ba14dbf86d3d6fad096c02;p=debian%2Fopenrocket diff --git a/android-libraries/achartengine/src/org/achartengine/chart/BarChart.java b/android-libraries/achartengine/src/org/achartengine/chart/BarChart.java new file mode 100644 index 00000000..d5d0fb23 --- /dev/null +++ b/android-libraries/achartengine/src/org/achartengine/chart/BarChart.java @@ -0,0 +1,329 @@ +/** + * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.achartengine.chart; + +import org.achartengine.model.XYMultipleSeriesDataset; +import org.achartengine.model.XYSeries; +import org.achartengine.renderer.SimpleSeriesRenderer; +import org.achartengine.renderer.XYMultipleSeriesRenderer; + +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Paint.Style; +import android.graphics.RectF; +import android.graphics.drawable.GradientDrawable; +import android.graphics.drawable.GradientDrawable.Orientation; + +/** + * The bar chart rendering class. + */ +public class BarChart extends XYChart { + /** The constant to identify this chart type. */ + public static final String TYPE = "Bar"; + /** The legend shape width. */ + private static final int SHAPE_WIDTH = 12; + /** The chart type. */ + protected Type mType = Type.DEFAULT; + + /** + * The bar chart type enum. + */ + public enum Type { + DEFAULT, STACKED; + } + + BarChart() { + } + + BarChart(Type type) { + mType = type; + } + + /** + * Builds a new bar chart instance. + * + * @param dataset the multiple series dataset + * @param renderer the multiple series renderer + * @param type the bar chart type + */ + public BarChart(XYMultipleSeriesDataset dataset, XYMultipleSeriesRenderer renderer, Type type) { + super(dataset, renderer); + mType = type; + } + + @Override + protected ClickableArea[] clickableAreasForPoints(float[] points, double[] values, + float yAxisValue, int seriesIndex, int startIndex) { + int seriesNr = mDataset.getSeriesCount(); + int length = points.length; + ClickableArea[] ret = new ClickableArea[length / 2]; + float halfDiffX = getHalfDiffX(points, length, seriesNr); + for (int i = 0; i < length; i += 2) { + float x = points[i]; + float y = points[i + 1]; + if (mType == Type.STACKED) { + ret[i / 2] = new ClickableArea(new RectF(x - halfDiffX, y, x + halfDiffX, yAxisValue), + values[i], values[i + 1]); + } else { + float startX = x - seriesNr * halfDiffX + seriesIndex * 2 * halfDiffX; + ret[i / 2] = new ClickableArea(new RectF(startX, y, startX + 2 * halfDiffX, yAxisValue), + values[i], values[i + 1]); + } + } + return ret; + } + + /** + * The graphical representation of a series. + * + * @param canvas the canvas to paint to + * @param paint the paint to be used for drawing + * @param points the array of points to be used for drawing the series + * @param seriesRenderer the series renderer + * @param yAxisValue the minimum value of the y axis + * @param seriesIndex the index of the series currently being drawn + * @param startIndex the start index of the rendering points + */ + public void drawSeries(Canvas canvas, Paint paint, float[] points, + SimpleSeriesRenderer seriesRenderer, float yAxisValue, int seriesIndex, int startIndex) { + int seriesNr = mDataset.getSeriesCount(); + int length = points.length; + paint.setColor(seriesRenderer.getColor()); + paint.setStyle(Style.FILL); + float halfDiffX = getHalfDiffX(points, length, seriesNr); + for (int i = 0; i < length; i += 2) { + float x = points[i]; + float y = points[i + 1]; + drawBar(canvas, x, yAxisValue, x, y, halfDiffX, seriesNr, seriesIndex, paint); + } + paint.setColor(seriesRenderer.getColor()); + } + + /** + * Draws a bar. + * + * @param canvas the canvas + * @param xMin the X axis minimum + * @param yMin the Y axis minimum + * @param xMax the X axis maximum + * @param yMax the Y axis maximum + * @param halfDiffX half the size of a bar + * @param seriesNr the total number of series + * @param seriesIndex the current series index + * @param paint the paint + */ + protected void drawBar(Canvas canvas, float xMin, float yMin, float xMax, float yMax, + float halfDiffX, int seriesNr, int seriesIndex, Paint paint) { + int scale = mDataset.getSeriesAt(seriesIndex).getScaleNumber(); + if (mType == Type.STACKED) { + drawBar(canvas, xMin - halfDiffX, yMax, xMax + halfDiffX, yMin, scale, seriesIndex, paint); + } else { + float startX = xMin - seriesNr * halfDiffX + seriesIndex * 2 * halfDiffX; + drawBar(canvas, startX, yMax, startX + 2 * halfDiffX, yMin, scale, seriesIndex, paint); + } + } + + /** + * Draws a bar. + * + * @param canvas the canvas + * @param xMin the X axis minimum + * @param yMin the Y axis minimum + * @param xMax the X axis maximum + * @param yMax the Y axis maximum + * @param scale the scale index + * @param seriesIndex the current series index + * @param paint the paint + */ + private void drawBar(Canvas canvas, float xMin, float yMin, float xMax, float yMax, int scale, + int seriesIndex, Paint paint) { + SimpleSeriesRenderer renderer = mRenderer.getSeriesRendererAt(seriesIndex); + if (renderer.isGradientEnabled()) { + float minY = (float) toScreenPoint(new double[] { 0, renderer.getGradientStopValue() }, scale)[1]; + float maxY = (float) toScreenPoint(new double[] { 0, renderer.getGradientStartValue() }, + scale)[1]; + float gradientMinY = Math.max(minY, Math.min(yMin, yMax)); + float gradientMaxY = Math.min(maxY, Math.max(yMin, yMax)); + int gradientMinColor = renderer.getGradientStopColor(); + int gradientMaxColor = renderer.getGradientStartColor(); + int gradientStartColor = gradientMaxColor; + int gradientStopColor = gradientMinColor; + + if (yMin < minY) { + paint.setColor(gradientMinColor); + canvas.drawRect(Math.round(xMin), Math.round(yMin), Math.round(xMax), + Math.round(gradientMinY), paint); + } else { + gradientStopColor = getGradientPartialColor(gradientMinColor, gradientMaxColor, + (maxY - gradientMinY) / (maxY - minY)); + } + if (yMax > maxY) { + paint.setColor(gradientMaxColor); + canvas.drawRect(Math.round(xMin), Math.round(gradientMaxY), Math.round(xMax), + Math.round(yMax), paint); + } else { + gradientStartColor = getGradientPartialColor(gradientMaxColor, gradientMinColor, + (gradientMaxY - minY) / (maxY - minY)); + } + GradientDrawable gradient = new GradientDrawable(Orientation.BOTTOM_TOP, new int[] { + gradientStartColor, gradientStopColor }); + gradient.setBounds(Math.round(xMin), Math.round(gradientMinY), Math.round(xMax), + Math.round(gradientMaxY)); + gradient.draw(canvas); + } else { + if (Math.abs(yMin - yMax) < 1) { + if (yMin < yMax) { + yMax = yMin + 1; + } else { + yMax = yMin - 1; + } + } + canvas + .drawRect(Math.round(xMin), Math.round(yMin), Math.round(xMax), Math.round(yMax), paint); + } + } + + private int getGradientPartialColor(int minColor, int maxColor, float fraction) { + int alpha = Math.round(fraction * Color.alpha(minColor) + (1 - fraction) + * Color.alpha(maxColor)); + int r = Math.round(fraction * Color.red(minColor) + (1 - fraction) * Color.red(maxColor)); + int g = Math.round(fraction * Color.green(minColor) + (1 - fraction) * Color.green(maxColor)); + int b = Math.round(fraction * Color.blue(minColor) + (1 - fraction) * Color.blue((maxColor))); + return Color.argb(alpha, r, g, b); + } + + /** + * The graphical representation of the series values as text. + * + * @param canvas the canvas to paint to + * @param series the series to be painted + * @param renderer the series renderer + * @param paint the paint to be used for drawing + * @param points the array of points to be used for drawing the series + * @param seriesIndex the index of the series currently being drawn + * @param startIndex the start index of the rendering points + */ + protected void drawChartValuesText(Canvas canvas, XYSeries series, SimpleSeriesRenderer renderer, + Paint paint, float[] points, int seriesIndex, int startIndex) { + int seriesNr = mDataset.getSeriesCount(); + float halfDiffX = getHalfDiffX(points, points.length, seriesNr); + for (int i = 0; i < points.length; i += 2) { + int index = startIndex + i / 2; + double value = series.getY(index); + if (!isNullValue(value)) { + float x = points[i]; + if (mType == Type.DEFAULT) { + x += seriesIndex * 2 * halfDiffX - (seriesNr - 1.5f) * halfDiffX; + } + if (value >= 0) { + drawText(canvas, getLabel(value), x, points[i + 1] - renderer.getChartValuesSpacing(), + paint, 0); + } else { + drawText(canvas, getLabel(value), x, points[i + 1] + renderer.getChartValuesTextSize() + + renderer.getChartValuesSpacing() - 3, paint, 0); + } + } + } + } + + /** + * Returns the legend shape width. + * + * @param seriesIndex the series index + * @return the legend shape width + */ + public int getLegendShapeWidth(int seriesIndex) { + return SHAPE_WIDTH; + } + + /** + * The graphical representation of the legend shape. + * + * @param canvas the canvas to paint to + * @param renderer the series renderer + * @param x the x value of the point the shape should be drawn at + * @param y the y value of the point the shape should be drawn at + * @param seriesIndex the series index + * @param paint the paint to be used for drawing + */ + public void drawLegendShape(Canvas canvas, SimpleSeriesRenderer renderer, float x, float y, + int seriesIndex, Paint paint) { + float halfShapeWidth = SHAPE_WIDTH / 2; + canvas.drawRect(x, y - halfShapeWidth, x + SHAPE_WIDTH, y + halfShapeWidth, paint); + } + + /** + * Calculates and returns the half-distance in the graphical representation of + * 2 consecutive points. + * + * @param points the points + * @param length the points length + * @param seriesNr the series number + * @return the calculated half-distance value + */ + protected float getHalfDiffX(float[] points, int length, int seriesNr) { + int div = length; + if (length > 2) { + div = length - 2; + } + float halfDiffX = (points[length - 2] - points[0]) / div; + if (halfDiffX == 0) { + halfDiffX = 10; + } + + if (mType != Type.STACKED) { + halfDiffX /= seriesNr; + } + return (float) (halfDiffX / (getCoeficient() * (1 + mRenderer.getBarSpacing()))); + } + + /** + * Returns the value of a constant used to calculate the half-distance. + * + * @return the constant value + */ + protected float getCoeficient() { + return 1f; + } + + /** + * Returns if the chart should display the null values. + * + * @return if null values should be rendered + */ + protected boolean isRenderNullValues() { + return true; + } + + /** + * Returns the default axis minimum. + * + * @return the default axis minimum + */ + public double getDefaultMinimum() { + return 0; + } + + /** + * Returns the chart type identifier. + * + * @return the chart type + */ + public String getChartType() { + return TYPE; + } +}