• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 package com.github.mikephil.charting.charts;
3 
4 import android.content.Context;
5 import android.graphics.Canvas;
6 import android.graphics.Color;
7 import android.graphics.RectF;
8 import android.util.AttributeSet;
9 
10 import com.github.mikephil.charting.components.YAxis;
11 import com.github.mikephil.charting.components.YAxis.AxisDependency;
12 import com.github.mikephil.charting.data.RadarData;
13 import com.github.mikephil.charting.highlight.RadarHighlighter;
14 import com.github.mikephil.charting.renderer.RadarChartRenderer;
15 import com.github.mikephil.charting.renderer.XAxisRendererRadarChart;
16 import com.github.mikephil.charting.renderer.YAxisRendererRadarChart;
17 import com.github.mikephil.charting.utils.Utils;
18 
19 /**
20  * Implementation of the RadarChart, a "spidernet"-like chart. It works best
21  * when displaying 5-10 entries per DataSet.
22  *
23  * @author Philipp Jahoda
24  */
25 public class RadarChart extends PieRadarChartBase<RadarData> {
26 
27     /**
28      * width of the main web lines
29      */
30     private float mWebLineWidth = 2.5f;
31 
32     /**
33      * width of the inner web lines
34      */
35     private float mInnerWebLineWidth = 1.5f;
36 
37     /**
38      * color for the main web lines
39      */
40     private int mWebColor = Color.rgb(122, 122, 122);
41 
42     /**
43      * color for the inner web
44      */
45     private int mWebColorInner = Color.rgb(122, 122, 122);
46 
47     /**
48      * transparency the grid is drawn with (0-255)
49      */
50     private int mWebAlpha = 150;
51 
52     /**
53      * flag indicating if the web lines should be drawn or not
54      */
55     private boolean mDrawWeb = true;
56 
57     /**
58      * modulus that determines how many labels and web-lines are skipped before the next is drawn
59      */
60     private int mSkipWebLineCount = 0;
61 
62     /**
63      * the object reprsenting the y-axis labels
64      */
65     private YAxis mYAxis;
66 
67     protected YAxisRendererRadarChart mYAxisRenderer;
68     protected XAxisRendererRadarChart mXAxisRenderer;
69 
RadarChart(Context context)70     public RadarChart(Context context) {
71         super(context);
72     }
73 
RadarChart(Context context, AttributeSet attrs)74     public RadarChart(Context context, AttributeSet attrs) {
75         super(context, attrs);
76     }
77 
RadarChart(Context context, AttributeSet attrs, int defStyle)78     public RadarChart(Context context, AttributeSet attrs, int defStyle) {
79         super(context, attrs, defStyle);
80     }
81 
82     @Override
init()83     protected void init() {
84         super.init();
85 
86         mYAxis = new YAxis(AxisDependency.LEFT);
87         mYAxis.setLabelXOffset(10f);
88 
89         mWebLineWidth = Utils.convertDpToPixel(1.5f);
90         mInnerWebLineWidth = Utils.convertDpToPixel(0.75f);
91 
92         mRenderer = new RadarChartRenderer(this, mAnimator, mViewPortHandler);
93         mYAxisRenderer = new YAxisRendererRadarChart(mViewPortHandler, mYAxis, this);
94         mXAxisRenderer = new XAxisRendererRadarChart(mViewPortHandler, mXAxis, this);
95 
96         mHighlighter = new RadarHighlighter(this);
97     }
98 
99     @Override
calcMinMax()100     protected void calcMinMax() {
101         super.calcMinMax();
102 
103         mYAxis.calculate(mData.getYMin(AxisDependency.LEFT), mData.getYMax(AxisDependency.LEFT));
104         mXAxis.calculate(0, mData.getMaxEntryCountSet().getEntryCount());
105     }
106 
107     @Override
notifyDataSetChanged()108     public void notifyDataSetChanged() {
109         if (mData == null)
110             return;
111 
112         calcMinMax();
113 
114         mYAxisRenderer.computeAxis(mYAxis.mAxisMinimum, mYAxis.mAxisMaximum, mYAxis.isInverted());
115         mXAxisRenderer.computeAxis(mXAxis.mAxisMinimum, mXAxis.mAxisMaximum, false);
116 
117         if (mLegend != null && !mLegend.isLegendCustom())
118             mLegendRenderer.computeLegend(mData);
119 
120         calculateOffsets();
121     }
122 
123     @Override
onDraw(Canvas canvas)124     protected void onDraw(Canvas canvas) {
125         super.onDraw(canvas);
126 
127         if (mData == null)
128             return;
129 
130 //        if (mYAxis.isEnabled())
131 //            mYAxisRenderer.computeAxis(mYAxis.mAxisMinimum, mYAxis.mAxisMaximum, mYAxis.isInverted());
132 
133         if (mXAxis.isEnabled())
134             mXAxisRenderer.computeAxis(mXAxis.mAxisMinimum, mXAxis.mAxisMaximum, false);
135 
136         mXAxisRenderer.renderAxisLabels(canvas);
137 
138         if (mDrawWeb)
139             mRenderer.drawExtras(canvas);
140 
141         if (mYAxis.isEnabled() && mYAxis.isDrawLimitLinesBehindDataEnabled())
142             mYAxisRenderer.renderLimitLines(canvas);
143 
144         mRenderer.drawData(canvas);
145 
146         if (valuesToHighlight())
147             mRenderer.drawHighlighted(canvas, mIndicesToHighlight);
148 
149         if (mYAxis.isEnabled() && !mYAxis.isDrawLimitLinesBehindDataEnabled())
150             mYAxisRenderer.renderLimitLines(canvas);
151 
152         mYAxisRenderer.renderAxisLabels(canvas);
153 
154         mRenderer.drawValues(canvas);
155 
156         mLegendRenderer.renderLegend(canvas);
157 
158         drawDescription(canvas);
159 
160         drawMarkers(canvas);
161     }
162 
163     /**
164      * Returns the factor that is needed to transform values into pixels.
165      *
166      * @return
167      */
getFactor()168     public float getFactor() {
169         RectF content = mViewPortHandler.getContentRect();
170         return Math.min(content.width() / 2f, content.height() / 2f) / mYAxis.mAxisRange;
171     }
172 
173     /**
174      * Returns the angle that each slice in the radar chart occupies.
175      *
176      * @return
177      */
getSliceAngle()178     public float getSliceAngle() {
179         return 360f / (float) mData.getMaxEntryCountSet().getEntryCount();
180     }
181 
182     @Override
getIndexForAngle(float angle)183     public int getIndexForAngle(float angle) {
184 
185         // take the current angle of the chart into consideration
186         float a = Utils.getNormalizedAngle(angle - getRotationAngle());
187 
188         float sliceangle = getSliceAngle();
189 
190         int max = mData.getMaxEntryCountSet().getEntryCount();
191 
192         int index = 0;
193 
194         for (int i = 0; i < max; i++) {
195 
196             float referenceAngle = sliceangle * (i + 1) - sliceangle / 2f;
197 
198             if (referenceAngle > a) {
199                 index = i;
200                 break;
201             }
202         }
203 
204         return index;
205     }
206 
207     /**
208      * Returns the object that represents all y-labels of the RadarChart.
209      *
210      * @return
211      */
getYAxis()212     public YAxis getYAxis() {
213         return mYAxis;
214     }
215 
216     /**
217      * Sets the width of the web lines that come from the center.
218      *
219      * @param width
220      */
setWebLineWidth(float width)221     public void setWebLineWidth(float width) {
222         mWebLineWidth = Utils.convertDpToPixel(width);
223     }
224 
getWebLineWidth()225     public float getWebLineWidth() {
226         return mWebLineWidth;
227     }
228 
229     /**
230      * Sets the width of the web lines that are in between the lines coming from
231      * the center.
232      *
233      * @param width
234      */
setWebLineWidthInner(float width)235     public void setWebLineWidthInner(float width) {
236         mInnerWebLineWidth = Utils.convertDpToPixel(width);
237     }
238 
getWebLineWidthInner()239     public float getWebLineWidthInner() {
240         return mInnerWebLineWidth;
241     }
242 
243     /**
244      * Sets the transparency (alpha) value for all web lines, default: 150, 255
245      * = 100% opaque, 0 = 100% transparent
246      *
247      * @param alpha
248      */
setWebAlpha(int alpha)249     public void setWebAlpha(int alpha) {
250         mWebAlpha = alpha;
251     }
252 
253     /**
254      * Returns the alpha value for all web lines.
255      *
256      * @return
257      */
getWebAlpha()258     public int getWebAlpha() {
259         return mWebAlpha;
260     }
261 
262     /**
263      * Sets the color for the web lines that come from the center. Don't forget
264      * to use getResources().getColor(...) when loading a color from the
265      * resources. Default: Color.rgb(122, 122, 122)
266      *
267      * @param color
268      */
setWebColor(int color)269     public void setWebColor(int color) {
270         mWebColor = color;
271     }
272 
getWebColor()273     public int getWebColor() {
274         return mWebColor;
275     }
276 
277     /**
278      * Sets the color for the web lines in between the lines that come from the
279      * center. Don't forget to use getResources().getColor(...) when loading a
280      * color from the resources. Default: Color.rgb(122, 122, 122)
281      *
282      * @param color
283      */
setWebColorInner(int color)284     public void setWebColorInner(int color) {
285         mWebColorInner = color;
286     }
287 
getWebColorInner()288     public int getWebColorInner() {
289         return mWebColorInner;
290     }
291 
292     /**
293      * If set to true, drawing the web is enabled, if set to false, drawing the
294      * whole web is disabled. Default: true
295      *
296      * @param enabled
297      */
setDrawWeb(boolean enabled)298     public void setDrawWeb(boolean enabled) {
299         mDrawWeb = enabled;
300     }
301 
302     /**
303      * Sets the number of web-lines that should be skipped on chart web before the
304      * next one is drawn. This targets the lines that come from the center of the RadarChart.
305      *
306      * @param count if count = 1 -> 1 line is skipped in between
307      */
setSkipWebLineCount(int count)308     public void setSkipWebLineCount(int count) {
309 
310         mSkipWebLineCount = Math.max(0, count);
311     }
312 
313     /**
314      * Returns the modulus that is used for skipping web-lines.
315      *
316      * @return
317      */
getSkipWebLineCount()318     public int getSkipWebLineCount() {
319         return mSkipWebLineCount;
320     }
321 
322     @Override
getRequiredLegendOffset()323     protected float getRequiredLegendOffset() {
324         return mLegendRenderer.getLabelPaint().getTextSize() * 4.f;
325     }
326 
327     @Override
getRequiredBaseOffset()328     protected float getRequiredBaseOffset() {
329         return mXAxis.isEnabled() && mXAxis.isDrawLabelsEnabled() ?
330                 mXAxis.mLabelRotatedWidth :
331                 Utils.convertDpToPixel(10f);
332     }
333 
334     @Override
getRadius()335     public float getRadius() {
336         RectF content = mViewPortHandler.getContentRect();
337         return Math.min(content.width() / 2f, content.height() / 2f);
338     }
339 
340     /**
341      * Returns the maximum value this chart can display on it's y-axis.
342      */
getYChartMax()343     public float getYChartMax() {
344         return mYAxis.mAxisMaximum;
345     }
346 
347     /**
348      * Returns the minimum value this chart can display on it's y-axis.
349      */
getYChartMin()350     public float getYChartMin() {
351         return mYAxis.mAxisMinimum;
352     }
353 
354     /**
355      * Returns the range of y-values this chart can display.
356      *
357      * @return
358      */
getYRange()359     public float getYRange() {
360         return mYAxis.mAxisRange;
361     }
362 }
363