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