create changelog entry
[debian/openrocket] / android-libraries / achartengine / src / org / achartengine / chart / DoughnutChart.java
1 /**\r
2  * Copyright (C) 2009 - 2012 SC 4ViewSoft SRL\r
3  *  \r
4  * Licensed under the Apache License, Version 2.0 (the "License");\r
5  * you may not use this file except in compliance with the License.\r
6  * You may obtain a copy of the License at\r
7  *  \r
8  *      http://www.apache.org/licenses/LICENSE-2.0\r
9  *  \r
10  * Unless required by applicable law or agreed to in writing, software\r
11  * distributed under the License is distributed on an "AS IS" BASIS,\r
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
13  * See the License for the specific language governing permissions and\r
14  * limitations under the License.\r
15  */\r
16 package org.achartengine.chart;\r
17 \r
18 import java.util.ArrayList;\r
19 import java.util.List;\r
20 \r
21 import org.achartengine.model.MultipleCategorySeries;\r
22 import org.achartengine.renderer.DefaultRenderer;\r
23 import org.achartengine.renderer.SimpleSeriesRenderer;\r
24 \r
25 import android.graphics.Canvas;\r
26 import android.graphics.Color;\r
27 import android.graphics.Paint;\r
28 import android.graphics.Paint.Style;\r
29 import android.graphics.RectF;\r
30 \r
31 /**\r
32  * The doughnut chart rendering class.\r
33  */\r
34 public class DoughnutChart extends RoundChart {\r
35   /** The series dataset. */\r
36   private MultipleCategorySeries mDataset;\r
37   /** A step variable to control the size of the legend shape. */\r
38   private int mStep;\r
39 \r
40   /**\r
41    * Builds a new doughnut chart instance.\r
42    * \r
43    * @param dataset the series dataset\r
44    * @param renderer the series renderer\r
45    */\r
46   public DoughnutChart(MultipleCategorySeries dataset, DefaultRenderer renderer) {\r
47     super(null, renderer);\r
48     mDataset = dataset;\r
49   }\r
50 \r
51   /**\r
52    * The graphical representation of the doughnut chart.\r
53    * \r
54    * @param canvas the canvas to paint to\r
55    * @param x the top left x value of the view to draw to\r
56    * @param y the top left y value of the view to draw to\r
57    * @param width the width of the view to draw to\r
58    * @param height the height of the view to draw to\r
59    * @param paint the paint\r
60    */\r
61   @Override\r
62   public void draw(Canvas canvas, int x, int y, int width, int height, Paint paint) {\r
63     paint.setAntiAlias(mRenderer.isAntialiasing());\r
64     paint.setStyle(Style.FILL);\r
65     paint.setTextSize(mRenderer.getLabelsTextSize());\r
66     int legendSize = getLegendSize(mRenderer, height / 5, 0);\r
67     int left = x;\r
68     int top = y;\r
69     int right = x + width;\r
70     int cLength = mDataset.getCategoriesCount();\r
71     String[] categories = new String[cLength];\r
72     for (int category = 0; category < cLength; category++) {\r
73       categories[category] = mDataset.getCategory(category);\r
74     }\r
75     if (mRenderer.isFitLegend()) {\r
76       legendSize = drawLegend(canvas, mRenderer, categories, left, right, y, width, height,\r
77           legendSize, paint, true);\r
78     }\r
79 \r
80     int bottom = y + height - legendSize;\r
81     drawBackground(mRenderer, canvas, x, y, width, height, paint, false, DefaultRenderer.NO_COLOR);\r
82     mStep = SHAPE_WIDTH * 3 / 4;\r
83 \r
84     int mRadius = Math.min(Math.abs(right - left), Math.abs(bottom - top));\r
85     double rCoef = 0.35 * mRenderer.getScale();\r
86     double decCoef = 0.2 / cLength;\r
87     int radius = (int) (mRadius * rCoef);\r
88     if (mCenterX == NO_VALUE) {\r
89       mCenterX = (left + right) / 2;\r
90     }\r
91     if (mCenterY == NO_VALUE) {\r
92       mCenterY = (bottom + top) / 2;\r
93     }\r
94     float shortRadius = radius * 0.9f;\r
95     float longRadius = radius * 1.1f;\r
96     List<RectF> prevLabelsBounds = new ArrayList<RectF>();\r
97     for (int category = 0; category < cLength; category++) {\r
98       int sLength = mDataset.getItemCount(category);\r
99       double total = 0;\r
100       String[] titles = new String[sLength];\r
101       for (int i = 0; i < sLength; i++) {\r
102         total += mDataset.getValues(category)[i];\r
103         titles[i] = mDataset.getTitles(category)[i];\r
104       }\r
105       float currentAngle = mRenderer.getStartAngle();\r
106       RectF oval = new RectF(mCenterX - radius, mCenterY - radius, mCenterX + radius, mCenterY\r
107           + radius);\r
108       for (int i = 0; i < sLength; i++) {\r
109         paint.setColor(mRenderer.getSeriesRendererAt(i).getColor());\r
110         float value = (float) mDataset.getValues(category)[i];\r
111         float angle = (float) (value / total * 360);\r
112         canvas.drawArc(oval, currentAngle, angle, true, paint);\r
113         drawLabel(canvas, mDataset.getTitles(category)[i], mRenderer, prevLabelsBounds, mCenterX,\r
114             mCenterY, shortRadius, longRadius, currentAngle, angle, left, right,\r
115             mRenderer.getLabelsColor(), paint, true);\r
116         currentAngle += angle;\r
117       }\r
118       radius -= (int) mRadius * decCoef;\r
119       shortRadius -= mRadius * decCoef - 2;\r
120       if (mRenderer.getBackgroundColor() != 0) {\r
121         paint.setColor(mRenderer.getBackgroundColor());\r
122       } else {\r
123         paint.setColor(Color.WHITE);\r
124       }\r
125       paint.setStyle(Style.FILL);\r
126       oval = new RectF(mCenterX - radius, mCenterY - radius, mCenterX + radius, mCenterY + radius);\r
127       canvas.drawArc(oval, 0, 360, true, paint);\r
128       radius -= 1;\r
129     }\r
130     prevLabelsBounds.clear();\r
131     drawLegend(canvas, mRenderer, categories, left, right, y, width, height, legendSize, paint,\r
132         false);\r
133     drawTitle(canvas, x, y, width, paint);\r
134   }\r
135 \r
136   /**\r
137    * Returns the legend shape width.\r
138    * \r
139    * @param seriesIndex the series index\r
140    * @return the legend shape width\r
141    */\r
142   public int getLegendShapeWidth(int seriesIndex) {\r
143     return SHAPE_WIDTH;\r
144   }\r
145 \r
146   /**\r
147    * The graphical representation of the legend shape.\r
148    * \r
149    * @param canvas the canvas to paint to\r
150    * @param renderer the series renderer\r
151    * @param x the x value of the point the shape should be drawn at\r
152    * @param y the y value of the point the shape should be drawn at\r
153    * @param seriesIndex the series index\r
154    * @param paint the paint to be used for drawing\r
155    */\r
156   public void drawLegendShape(Canvas canvas, SimpleSeriesRenderer renderer, float x, float y,\r
157       int seriesIndex, Paint paint) {\r
158     mStep--;\r
159     canvas.drawCircle(x + SHAPE_WIDTH - mStep, y, mStep, paint);\r
160   }\r
161 \r
162 }\r