Skip to content

Commit 9043118

Browse files
authored
Merge pull request #239 from AppDevNext/bar-rounded-corners
Add RoundedBar renderer for corner radius positive/negative BarChart
2 parents 15f2ea5 + 814de5e commit 9043118

File tree

9 files changed

+982
-0
lines changed

9 files changed

+982
-0
lines changed

MPChartExample/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
<activity android:name="HorizontalBarChartActivity" />
2626
<activity android:name="HorizontalBarNegativeChartActivity" />
2727
<activity android:name="PieChartActivity" />
28+
<activity android:name=".PieChartRoundedActivity" />
2829
<activity android:name="PiePolylineChartActivity" />
2930
<activity android:name="MultiLineChartActivity" />
3031
<activity android:name="BarChartActivityMultiDataset" />
Lines changed: 334 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,334 @@
1+
2+
package com.xxmassdeveloper.mpchartexample;
3+
4+
import android.Manifest;
5+
import android.content.Intent;
6+
import android.content.pm.PackageManager;
7+
import android.graphics.Color;
8+
import android.graphics.Typeface;
9+
import android.net.Uri;
10+
import android.os.Bundle;
11+
import android.text.SpannableString;
12+
import android.text.style.ForegroundColorSpan;
13+
import android.text.style.RelativeSizeSpan;
14+
import android.text.style.StyleSpan;
15+
import android.util.Log;
16+
import android.view.Menu;
17+
import android.view.MenuItem;
18+
import android.view.WindowManager;
19+
import android.widget.SeekBar;
20+
import android.widget.SeekBar.OnSeekBarChangeListener;
21+
import android.widget.TextView;
22+
23+
import com.github.mikephil.charting.animation.Easing;
24+
import com.github.mikephil.charting.charts.PieChart;
25+
import com.github.mikephil.charting.components.Legend;
26+
import com.github.mikephil.charting.data.Entry;
27+
import com.github.mikephil.charting.data.PieData;
28+
import com.github.mikephil.charting.data.PieDataSet;
29+
import com.github.mikephil.charting.data.PieEntry;
30+
import com.github.mikephil.charting.formatter.PercentFormatter;
31+
import com.github.mikephil.charting.highlight.Highlight;
32+
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
33+
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
34+
import com.github.mikephil.charting.renderer.PieChartRenderer;
35+
import com.github.mikephil.charting.utils.ColorTemplate;
36+
import com.github.mikephil.charting.utils.MPPointF;
37+
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
38+
39+
import java.util.ArrayList;
40+
41+
import androidx.core.content.ContextCompat;
42+
43+
public class PieChartRoundedActivity extends DemoBase implements OnSeekBarChangeListener,
44+
OnChartValueSelectedListener {
45+
46+
private PieChart chart;
47+
private SeekBar seekBarX, seekBarY;
48+
private TextView tvX, tvY;
49+
50+
@Override
51+
protected void onCreate(Bundle savedInstanceState) {
52+
super.onCreate(savedInstanceState);
53+
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
54+
WindowManager.LayoutParams.FLAG_FULLSCREEN);
55+
setContentView(R.layout.activity_piechart);
56+
57+
setTitle("PieChartActivity");
58+
59+
tvX = findViewById(R.id.tvXMax);
60+
tvY = findViewById(R.id.tvYMax);
61+
62+
seekBarX = findViewById(R.id.seekBarX);
63+
seekBarY = findViewById(R.id.seekBarY);
64+
65+
seekBarX.setOnSeekBarChangeListener(this);
66+
seekBarY.setOnSeekBarChangeListener(this);
67+
68+
chart = findViewById(R.id.chart1);
69+
chart.setUsePercentValues(true);
70+
chart.getDescription().setEnabled(false);
71+
chart.setExtraOffsets(5, 10, 5, 5);
72+
73+
chart.setDragDecelerationFrictionCoef(0.95f);
74+
75+
chart.setCenterTextTypeface(tfLight);
76+
chart.setCenterText(generateCenterSpannableText());
77+
78+
chart.setDrawHoleEnabled(true);
79+
chart.setHoleColor(Color.TRANSPARENT);
80+
81+
chart.setTransparentCircleColor(Color.TRANSPARENT);
82+
chart.setTransparentCircleAlpha(110);
83+
84+
chart.setHoleRadius(50f);
85+
86+
chart.setTransparentCircleRadius(0f);
87+
88+
chart.setDrawCenterText(true);
89+
90+
chart.setRotationAngle(0);
91+
// enable rotation of the chart by touch
92+
chart.setRotationEnabled(true);
93+
chart.setHighlightPerTapEnabled(true);
94+
95+
// chart.setUnit(" €");
96+
// chart.setDrawUnitsInChart(true);
97+
98+
// add a selection listener
99+
chart.setOnChartValueSelectedListener(this);
100+
101+
seekBarX.setProgress(4);
102+
seekBarY.setProgress(10);
103+
104+
chart.animateY(1400, Easing.EaseInOutQuad);
105+
// chart.spin(2000, 0, 360);
106+
107+
Legend l = chart.getLegend();
108+
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
109+
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
110+
l.setOrientation(Legend.LegendOrientation.VERTICAL);
111+
l.setDrawInside(false);
112+
l.setXEntrySpace(7f);
113+
l.setYEntrySpace(0f);
114+
l.setYOffset(0f);
115+
116+
// entry label styling
117+
chart.setEntryLabelColor(Color.WHITE);
118+
chart.setEntryLabelTypeface(tfRegular);
119+
chart.setEntryLabelTextSize(12f);
120+
}
121+
122+
private void setData(int count, float range) {
123+
ArrayList<PieEntry> entries = new ArrayList<>();
124+
Double[] sampleValues = DataTools.Companion.getValues(100);
125+
126+
// NOTE: The order of the entries when being added to the entries array determines their position around the center of
127+
// the chart.
128+
for (int i = 0; i < count ; i++) {
129+
entries.add(new PieEntry((float) ((sampleValues[i].floatValue() * range) + range / 5),
130+
parties[i % parties.length],
131+
getResources().getDrawable(R.drawable.star)));
132+
}
133+
134+
PieDataSet dataSet = new PieDataSet(entries, "Election Results");
135+
136+
dataSet.setDrawIcons(false);
137+
138+
dataSet.setSliceSpace(3f);
139+
dataSet.setIconsOffset(new MPPointF(0, 40));
140+
dataSet.setSelectionShift(5f);
141+
142+
// add a lot of colors
143+
144+
ArrayList<Integer> colors = new ArrayList<>();
145+
146+
for (int c : ColorTemplate.VORDIPLOM_COLORS)
147+
colors.add(c);
148+
149+
for (int c : ColorTemplate.JOYFUL_COLORS)
150+
colors.add(c);
151+
152+
for (int c : ColorTemplate.COLORFUL_COLORS)
153+
colors.add(c);
154+
155+
for (int c : ColorTemplate.LIBERTY_COLORS)
156+
colors.add(c);
157+
158+
for (int c : ColorTemplate.PASTEL_COLORS)
159+
colors.add(c);
160+
161+
colors.add(ColorTemplate.getHoloBlue());
162+
163+
dataSet.setColors(colors);
164+
//dataSet.setSelectionShift(0f);
165+
166+
PieData data = new PieData(dataSet);
167+
data.setValueFormatter(new PercentFormatter());
168+
data.setValueTextSize(11f);
169+
data.setValueTextColor(Color.WHITE);
170+
data.setValueTypeface(tfLight);
171+
chart.setData(data);
172+
173+
// undo all highlights
174+
chart.highlightValues(null);
175+
176+
PieChartRenderer renderer =(PieChartRenderer) chart.getRenderer();
177+
renderer.setRoundedCornerRadius(30f);
178+
dataSet.setSliceSpace(renderer.getRoundedCornerRadius()/2);
179+
180+
chart.invalidate();
181+
}
182+
183+
@Override
184+
public boolean onCreateOptionsMenu(Menu menu) {
185+
getMenuInflater().inflate(R.menu.pie, menu);
186+
return true;
187+
}
188+
189+
@Override
190+
public boolean onOptionsItemSelected(MenuItem item) {
191+
192+
switch (item.getItemId()) {
193+
case R.id.viewGithub: {
194+
Intent i = new Intent(Intent.ACTION_VIEW);
195+
i.setData(Uri.parse("https://github.com/AppDevNext/AndroidChart/blob/master/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/PieChartActivity.java"));
196+
startActivity(i);
197+
break;
198+
}
199+
case R.id.actionToggleValues: {
200+
for (IDataSet<?> set : chart.getData().getDataSets())
201+
set.setDrawValues(!set.isDrawValuesEnabled());
202+
203+
chart.invalidate();
204+
break;
205+
}
206+
case R.id.actionToggleIcons: {
207+
for (IDataSet<?> set : chart.getData().getDataSets())
208+
set.setDrawIcons(!set.isDrawIconsEnabled());
209+
210+
chart.invalidate();
211+
break;
212+
}
213+
case R.id.actionToggleHole: {
214+
if (chart.isDrawHoleEnabled())
215+
chart.setDrawHoleEnabled(false);
216+
else
217+
chart.setDrawHoleEnabled(true);
218+
chart.invalidate();
219+
break;
220+
}
221+
case R.id.actionToggleMinAngles: {
222+
if (chart.getMinAngleForSlices() == 0f)
223+
chart.setMinAngleForSlices(36f);
224+
else
225+
chart.setMinAngleForSlices(0f);
226+
chart.notifyDataSetChanged();
227+
chart.invalidate();
228+
break;
229+
}
230+
case R.id.actionToggleCurvedSlices: {
231+
boolean toSet = !chart.isDrawRoundedSlicesEnabled() || !chart.isDrawHoleEnabled();
232+
chart.setDrawRoundedSlices(toSet);
233+
if (toSet && !chart.isDrawHoleEnabled()) {
234+
chart.setDrawHoleEnabled(true);
235+
}
236+
if (toSet && chart.isDrawSlicesUnderHoleEnabled()) {
237+
chart.setDrawSlicesUnderHole(false);
238+
}
239+
chart.invalidate();
240+
break;
241+
}
242+
case R.id.actionDrawCenter: {
243+
if (chart.isDrawCenterTextEnabled())
244+
chart.setDrawCenterText(false);
245+
else
246+
chart.setDrawCenterText(true);
247+
chart.invalidate();
248+
break;
249+
}
250+
case R.id.actionToggleXValues: {
251+
252+
chart.setDrawEntryLabels(!chart.isDrawEntryLabelsEnabled());
253+
chart.invalidate();
254+
break;
255+
}
256+
case R.id.actionTogglePercent:
257+
chart.setUsePercentValues(!chart.isUsePercentValuesEnabled());
258+
chart.invalidate();
259+
break;
260+
case R.id.animateX: {
261+
chart.animateX(1400);
262+
break;
263+
}
264+
case R.id.animateY: {
265+
chart.animateY(1400);
266+
break;
267+
}
268+
case R.id.animateXY: {
269+
chart.animateXY(1400, 1400);
270+
break;
271+
}
272+
case R.id.actionToggleSpin: {
273+
chart.spin(1000, chart.getRotationAngle(), chart.getRotationAngle() + 360, Easing.EaseInOutCubic);
274+
break;
275+
}
276+
case R.id.actionSave: {
277+
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
278+
saveToGallery();
279+
} else {
280+
requestStoragePermission(chart);
281+
}
282+
break;
283+
}
284+
}
285+
return true;
286+
}
287+
288+
@Override
289+
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
290+
291+
tvX.setText(String.valueOf(seekBarX.getProgress()));
292+
tvY.setText(String.valueOf(seekBarY.getProgress()));
293+
294+
setData(seekBarX.getProgress(), seekBarY.getProgress());
295+
}
296+
297+
@Override
298+
protected void saveToGallery() {
299+
saveToGallery(chart, "PieChartActivity");
300+
}
301+
302+
private SpannableString generateCenterSpannableText() {
303+
304+
SpannableString s = new SpannableString("MPAndroidChart\ndeveloped by Philipp Jahoda");
305+
s.setSpan(new RelativeSizeSpan(1.7f), 0, 14, 0);
306+
s.setSpan(new StyleSpan(Typeface.NORMAL), 14, s.length() - 15, 0);
307+
s.setSpan(new ForegroundColorSpan(Color.GRAY), 14, s.length() - 15, 0);
308+
s.setSpan(new RelativeSizeSpan(.8f), 14, s.length() - 15, 0);
309+
s.setSpan(new StyleSpan(Typeface.ITALIC), s.length() - 14, s.length(), 0);
310+
s.setSpan(new ForegroundColorSpan(ColorTemplate.getHoloBlue()), s.length() - 14, s.length(), 0);
311+
return s;
312+
}
313+
314+
@Override
315+
public void onValueSelected(Entry e, Highlight h) {
316+
317+
if (e == null)
318+
return;
319+
Log.i("VAL SELECTED",
320+
"Value: " + e.getY() + ", index: " + h.getX()
321+
+ ", DataSet index: " + h.getDataSetIndex());
322+
}
323+
324+
@Override
325+
public void onNothingSelected() {
326+
Log.i("PieChart", "nothing selected");
327+
}
328+
329+
@Override
330+
public void onStartTrackingTouch(SeekBar seekBar) {}
331+
332+
@Override
333+
public void onStopTrackingTouch(SeekBar seekBar) {}
334+
}

MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/notimportant/MainActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ class MainActivity : AppCompatActivity(), OnItemClickListener {
9191

9292
add(19, ContentItem("Pie Charts"))
9393
add(20, ContentItem("Basic", "Simple pie chart.", PieChartActivity::class.java))
94+
add(20, ContentItem("Basic", "Rounded pie chart.", PieChartRoundedActivity::class.java))
9495
add(21, ContentItem("Value Lines", "Stylish lines drawn outward from slices.", PiePolylineChartActivity::class.java))
9596
add(22, ContentItem("Half Pie", "180° (half) pie chart.", HalfPieChartActivity::class.java))
9697
add(23, ContentItem("Specific positions", "This demonstrates how to pass a list of specific positions for lines and labels on x and y axis", SpecificPositionsLineChartActivity::class.java))

0 commit comments

Comments
 (0)