Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RoundedBar renderer for corner radius positive/negative BarChart #239

Merged
merged 6 commits into from
Jun 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions MPChartExample/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
<activity android:name="HorizontalBarChartActivity" />
<activity android:name="HorizontalBarNegativeChartActivity" />
<activity android:name="PieChartActivity" />
<activity android:name=".PieChartRoundedActivity" />
<activity android:name="PiePolylineChartActivity" />
<activity android:name="MultiLineChartActivity" />
<activity android:name="BarChartActivityMultiDataset" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,334 @@

package com.xxmassdeveloper.mpchartexample;

import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.graphics.Typeface;
import android.net.Uri;
import android.os.Bundle;
import android.text.SpannableString;
import android.text.style.ForegroundColorSpan;
import android.text.style.RelativeSizeSpan;
import android.text.style.StyleSpan;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.WindowManager;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;

import com.github.mikephil.charting.animation.Easing;
import com.github.mikephil.charting.charts.PieChart;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.data.PieData;
import com.github.mikephil.charting.data.PieDataSet;
import com.github.mikephil.charting.data.PieEntry;
import com.github.mikephil.charting.formatter.PercentFormatter;
import com.github.mikephil.charting.highlight.Highlight;
import com.github.mikephil.charting.interfaces.datasets.IDataSet;
import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
import com.github.mikephil.charting.renderer.PieChartRenderer;
import com.github.mikephil.charting.utils.ColorTemplate;
import com.github.mikephil.charting.utils.MPPointF;
import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;

import java.util.ArrayList;

import androidx.core.content.ContextCompat;

public class PieChartRoundedActivity extends DemoBase implements OnSeekBarChangeListener,
OnChartValueSelectedListener {

private PieChart chart;
private SeekBar seekBarX, seekBarY;
private TextView tvX, tvY;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.activity_piechart);

setTitle("PieChartActivity");

tvX = findViewById(R.id.tvXMax);
tvY = findViewById(R.id.tvYMax);

seekBarX = findViewById(R.id.seekBarX);
seekBarY = findViewById(R.id.seekBarY);

seekBarX.setOnSeekBarChangeListener(this);
seekBarY.setOnSeekBarChangeListener(this);

chart = findViewById(R.id.chart1);
chart.setUsePercentValues(true);
chart.getDescription().setEnabled(false);
chart.setExtraOffsets(5, 10, 5, 5);

chart.setDragDecelerationFrictionCoef(0.95f);

chart.setCenterTextTypeface(tfLight);
chart.setCenterText(generateCenterSpannableText());

chart.setDrawHoleEnabled(true);
chart.setHoleColor(Color.TRANSPARENT);

chart.setTransparentCircleColor(Color.TRANSPARENT);
chart.setTransparentCircleAlpha(110);

chart.setHoleRadius(50f);

chart.setTransparentCircleRadius(0f);

chart.setDrawCenterText(true);

chart.setRotationAngle(0);
// enable rotation of the chart by touch
chart.setRotationEnabled(true);
chart.setHighlightPerTapEnabled(true);

// chart.setUnit(" €");
// chart.setDrawUnitsInChart(true);

// add a selection listener
chart.setOnChartValueSelectedListener(this);

seekBarX.setProgress(4);
seekBarY.setProgress(10);

chart.animateY(1400, Easing.EaseInOutQuad);
// chart.spin(2000, 0, 360);

Legend l = chart.getLegend();
l.setVerticalAlignment(Legend.LegendVerticalAlignment.TOP);
l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT);
l.setOrientation(Legend.LegendOrientation.VERTICAL);
l.setDrawInside(false);
l.setXEntrySpace(7f);
l.setYEntrySpace(0f);
l.setYOffset(0f);

// entry label styling
chart.setEntryLabelColor(Color.WHITE);
chart.setEntryLabelTypeface(tfRegular);
chart.setEntryLabelTextSize(12f);
}

private void setData(int count, float range) {
ArrayList<PieEntry> entries = new ArrayList<>();
Double[] sampleValues = DataTools.Companion.getValues(100);

// NOTE: The order of the entries when being added to the entries array determines their position around the center of
// the chart.
for (int i = 0; i < count ; i++) {
entries.add(new PieEntry((float) ((sampleValues[i].floatValue() * range) + range / 5),
parties[i % parties.length],
getResources().getDrawable(R.drawable.star)));
}

PieDataSet dataSet = new PieDataSet(entries, "Election Results");

dataSet.setDrawIcons(false);

dataSet.setSliceSpace(3f);
dataSet.setIconsOffset(new MPPointF(0, 40));
dataSet.setSelectionShift(5f);

// add a lot of colors

ArrayList<Integer> colors = new ArrayList<>();

for (int c : ColorTemplate.VORDIPLOM_COLORS)
colors.add(c);

for (int c : ColorTemplate.JOYFUL_COLORS)
colors.add(c);

for (int c : ColorTemplate.COLORFUL_COLORS)
colors.add(c);

for (int c : ColorTemplate.LIBERTY_COLORS)
colors.add(c);

for (int c : ColorTemplate.PASTEL_COLORS)
colors.add(c);

colors.add(ColorTemplate.getHoloBlue());

dataSet.setColors(colors);
//dataSet.setSelectionShift(0f);

PieData data = new PieData(dataSet);
data.setValueFormatter(new PercentFormatter());
data.setValueTextSize(11f);
data.setValueTextColor(Color.WHITE);
data.setValueTypeface(tfLight);
chart.setData(data);

// undo all highlights
chart.highlightValues(null);

PieChartRenderer renderer =(PieChartRenderer) chart.getRenderer();
renderer.setRoundedCornerRadius(30f);
dataSet.setSliceSpace(renderer.getRoundedCornerRadius()/2);

chart.invalidate();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.pie, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {

switch (item.getItemId()) {
case R.id.viewGithub: {
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(Uri.parse("https://github.com/AppDevNext/AndroidChart/blob/master/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/PieChartActivity.java"));
startActivity(i);
break;
}
case R.id.actionToggleValues: {
for (IDataSet<?> set : chart.getData().getDataSets())
set.setDrawValues(!set.isDrawValuesEnabled());

chart.invalidate();
break;
}
case R.id.actionToggleIcons: {
for (IDataSet<?> set : chart.getData().getDataSets())
set.setDrawIcons(!set.isDrawIconsEnabled());

chart.invalidate();
break;
}
case R.id.actionToggleHole: {
if (chart.isDrawHoleEnabled())
chart.setDrawHoleEnabled(false);
else
chart.setDrawHoleEnabled(true);
chart.invalidate();
break;
}
case R.id.actionToggleMinAngles: {
if (chart.getMinAngleForSlices() == 0f)
chart.setMinAngleForSlices(36f);
else
chart.setMinAngleForSlices(0f);
chart.notifyDataSetChanged();
chart.invalidate();
break;
}
case R.id.actionToggleCurvedSlices: {
boolean toSet = !chart.isDrawRoundedSlicesEnabled() || !chart.isDrawHoleEnabled();
chart.setDrawRoundedSlices(toSet);
if (toSet && !chart.isDrawHoleEnabled()) {
chart.setDrawHoleEnabled(true);
}
if (toSet && chart.isDrawSlicesUnderHoleEnabled()) {
chart.setDrawSlicesUnderHole(false);
}
chart.invalidate();
break;
}
case R.id.actionDrawCenter: {
if (chart.isDrawCenterTextEnabled())
chart.setDrawCenterText(false);
else
chart.setDrawCenterText(true);
chart.invalidate();
break;
}
case R.id.actionToggleXValues: {

chart.setDrawEntryLabels(!chart.isDrawEntryLabelsEnabled());
chart.invalidate();
break;
}
case R.id.actionTogglePercent:
chart.setUsePercentValues(!chart.isUsePercentValuesEnabled());
chart.invalidate();
break;
case R.id.animateX: {
chart.animateX(1400);
break;
}
case R.id.animateY: {
chart.animateY(1400);
break;
}
case R.id.animateXY: {
chart.animateXY(1400, 1400);
break;
}
case R.id.actionToggleSpin: {
chart.spin(1000, chart.getRotationAngle(), chart.getRotationAngle() + 360, Easing.EaseInOutCubic);
break;
}
case R.id.actionSave: {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
saveToGallery();
} else {
requestStoragePermission(chart);
}
break;
}
}
return true;
}

@Override
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

tvX.setText(String.valueOf(seekBarX.getProgress()));
tvY.setText(String.valueOf(seekBarY.getProgress()));

setData(seekBarX.getProgress(), seekBarY.getProgress());
}

@Override
protected void saveToGallery() {
saveToGallery(chart, "PieChartActivity");
}

private SpannableString generateCenterSpannableText() {

SpannableString s = new SpannableString("MPAndroidChart\ndeveloped by Philipp Jahoda");
s.setSpan(new RelativeSizeSpan(1.7f), 0, 14, 0);
s.setSpan(new StyleSpan(Typeface.NORMAL), 14, s.length() - 15, 0);
s.setSpan(new ForegroundColorSpan(Color.GRAY), 14, s.length() - 15, 0);
s.setSpan(new RelativeSizeSpan(.8f), 14, s.length() - 15, 0);
s.setSpan(new StyleSpan(Typeface.ITALIC), s.length() - 14, s.length(), 0);
s.setSpan(new ForegroundColorSpan(ColorTemplate.getHoloBlue()), s.length() - 14, s.length(), 0);
return s;
}

@Override
public void onValueSelected(Entry e, Highlight h) {

if (e == null)
return;
Log.i("VAL SELECTED",
"Value: " + e.getY() + ", index: " + h.getX()
+ ", DataSet index: " + h.getDataSetIndex());
}

@Override
public void onNothingSelected() {
Log.i("PieChart", "nothing selected");
}

@Override
public void onStartTrackingTouch(SeekBar seekBar) {}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ class MainActivity : AppCompatActivity(), OnItemClickListener {

add(19, ContentItem("Pie Charts"))
add(20, ContentItem("Basic", "Simple pie chart.", PieChartActivity::class.java))
add(20, ContentItem("Basic", "Rounded pie chart.", PieChartRoundedActivity::class.java))
add(21, ContentItem("Value Lines", "Stylish lines drawn outward from slices.", PiePolylineChartActivity::class.java))
add(22, ContentItem("Half Pie", "180° (half) pie chart.", HalfPieChartActivity::class.java))
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))
Expand Down
Loading
Loading