1 package com.xxmassdeveloper.mpchartexample; 2 3 import android.Manifest; 4 import android.content.Intent; 5 import android.content.pm.PackageManager; 6 import android.graphics.Color; 7 import android.net.Uri; 8 import android.os.Bundle; 9 import androidx.core.content.ContextCompat; 10 import android.util.Log; 11 import android.view.Menu; 12 import android.view.MenuItem; 13 import android.view.WindowManager; 14 import android.widget.SeekBar; 15 import android.widget.SeekBar.OnSeekBarChangeListener; 16 import android.widget.TextView; 17 18 import com.github.mikephil.charting.charts.BarChart; 19 import com.github.mikephil.charting.components.Legend; 20 import com.github.mikephil.charting.components.XAxis; 21 import com.github.mikephil.charting.components.XAxis.XAxisPosition; 22 import com.github.mikephil.charting.components.YAxis; 23 import com.github.mikephil.charting.data.BarData; 24 import com.github.mikephil.charting.data.BarDataSet; 25 import com.github.mikephil.charting.data.BarEntry; 26 import com.github.mikephil.charting.data.Entry; 27 import com.github.mikephil.charting.highlight.Highlight; 28 import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; 29 import com.github.mikephil.charting.listener.OnChartValueSelectedListener; 30 import com.github.mikephil.charting.utils.ColorTemplate; 31 import com.xxmassdeveloper.mpchartexample.custom.MyAxisValueFormatter; 32 import com.xxmassdeveloper.mpchartexample.custom.MyValueFormatter; 33 import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase; 34 35 import java.util.ArrayList; 36 import java.util.List; 37 38 public class StackedBarActivity extends DemoBase implements OnSeekBarChangeListener, OnChartValueSelectedListener { 39 40 private BarChart chart; 41 private SeekBar seekBarX, seekBarY; 42 private TextView tvX, tvY; 43 44 @Override onCreate(Bundle savedInstanceState)45 protected void onCreate(Bundle savedInstanceState) { 46 super.onCreate(savedInstanceState); 47 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); 48 setContentView(R.layout.activity_barchart); 49 50 setTitle("StackedBarActivity"); 51 52 tvX = findViewById(R.id.tvXMax); 53 tvY = findViewById(R.id.tvYMax); 54 55 seekBarX = findViewById(R.id.seekBar1); 56 seekBarX.setOnSeekBarChangeListener(this); 57 58 seekBarY = findViewById(R.id.seekBar2); 59 seekBarY.setOnSeekBarChangeListener(this); 60 61 chart = findViewById(R.id.chart1); 62 chart.setOnChartValueSelectedListener(this); 63 64 chart.getDescription().setEnabled(false); 65 66 // if more than 60 entries are displayed in the chart, no values will be 67 // drawn 68 chart.setMaxVisibleValueCount(40); 69 70 // scaling can now only be done on x- and y-axis separately 71 chart.setPinchZoom(false); 72 73 chart.setDrawGridBackground(false); 74 chart.setDrawBarShadow(false); 75 76 chart.setDrawValueAboveBar(false); 77 chart.setHighlightFullBarEnabled(false); 78 79 // change the position of the y-labels 80 YAxis leftAxis = chart.getAxisLeft(); 81 leftAxis.setValueFormatter(new MyAxisValueFormatter()); 82 leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true) 83 chart.getAxisRight().setEnabled(false); 84 85 XAxis xLabels = chart.getXAxis(); 86 xLabels.setPosition(XAxisPosition.TOP); 87 88 // chart.setDrawXLabels(false); 89 // chart.setDrawYLabels(false); 90 91 // setting data 92 seekBarX.setProgress(12); 93 seekBarY.setProgress(100); 94 95 Legend l = chart.getLegend(); 96 l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM); 97 l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.RIGHT); 98 l.setOrientation(Legend.LegendOrientation.HORIZONTAL); 99 l.setDrawInside(false); 100 l.setFormSize(8f); 101 l.setFormToTextSpace(4f); 102 l.setXEntrySpace(6f); 103 104 // chart.setDrawLegend(false); 105 } 106 107 @Override onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)108 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 109 110 tvX.setText(String.valueOf(seekBarX.getProgress())); 111 tvY.setText(String.valueOf(seekBarY.getProgress())); 112 113 ArrayList<BarEntry> values = new ArrayList<>(); 114 115 for (int i = 0; i < seekBarX.getProgress(); i++) { 116 float mul = (seekBarY.getProgress() + 1); 117 float val1 = (float) (Math.random() * mul) + mul / 3; 118 float val2 = (float) (Math.random() * mul) + mul / 3; 119 float val3 = (float) (Math.random() * mul) + mul / 3; 120 121 values.add(new BarEntry( 122 i, 123 new float[]{val1, val2, val3}, 124 getResources().getDrawable(R.drawable.star))); 125 } 126 127 BarDataSet set1; 128 129 if (chart.getData() != null && 130 chart.getData().getDataSetCount() > 0) { 131 set1 = (BarDataSet) chart.getData().getDataSetByIndex(0); 132 set1.setValues(values); 133 chart.getData().notifyDataChanged(); 134 chart.notifyDataSetChanged(); 135 } else { 136 set1 = new BarDataSet(values, "Statistics Vienna 2014"); 137 set1.setDrawIcons(false); 138 set1.setColors(getColors()); 139 set1.setStackLabels(new String[]{"Births", "Divorces", "Marriages"}); 140 141 ArrayList<IBarDataSet> dataSets = new ArrayList<>(); 142 dataSets.add(set1); 143 144 BarData data = new BarData(dataSets); 145 data.setValueFormatter(new MyValueFormatter()); 146 data.setValueTextColor(Color.WHITE); 147 148 chart.setData(data); 149 } 150 151 chart.setFitBars(true); 152 chart.invalidate(); 153 } 154 155 @Override onCreateOptionsMenu(Menu menu)156 public boolean onCreateOptionsMenu(Menu menu) { 157 getMenuInflater().inflate(R.menu.bar, menu); 158 return true; 159 } 160 161 @Override onOptionsItemSelected(MenuItem item)162 public boolean onOptionsItemSelected(MenuItem item) { 163 164 switch (item.getItemId()) { 165 case R.id.viewGithub: { 166 Intent i = new Intent(Intent.ACTION_VIEW); 167 i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/StackedBarActivity.java")); 168 startActivity(i); 169 break; 170 } 171 case R.id.actionToggleValues: { 172 List<IBarDataSet> sets = chart.getData() 173 .getDataSets(); 174 175 for (IBarDataSet iSet : sets) { 176 177 BarDataSet set = (BarDataSet) iSet; 178 set.setDrawValues(!set.isDrawValuesEnabled()); 179 } 180 181 chart.invalidate(); 182 break; 183 } 184 case R.id.actionToggleIcons: { 185 List<IBarDataSet> sets = chart.getData() 186 .getDataSets(); 187 188 for (IBarDataSet iSet : sets) { 189 190 BarDataSet set = (BarDataSet) iSet; 191 set.setDrawIcons(!set.isDrawIconsEnabled()); 192 } 193 194 chart.invalidate(); 195 break; 196 } 197 case R.id.actionToggleHighlight: { 198 if (chart.getData() != null) { 199 chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled()); 200 chart.invalidate(); 201 } 202 break; 203 } 204 case R.id.actionTogglePinch: { 205 if (chart.isPinchZoomEnabled()) 206 chart.setPinchZoom(false); 207 else 208 chart.setPinchZoom(true); 209 210 chart.invalidate(); 211 break; 212 } 213 case R.id.actionToggleAutoScaleMinMax: { 214 chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled()); 215 chart.notifyDataSetChanged(); 216 break; 217 } 218 case R.id.actionToggleBarBorders: { 219 for (IBarDataSet set : chart.getData().getDataSets()) 220 ((BarDataSet) set).setBarBorderWidth(set.getBarBorderWidth() == 1.f ? 0.f : 1.f); 221 222 chart.invalidate(); 223 break; 224 } 225 case R.id.animateX: { 226 chart.animateX(2000); 227 break; 228 } 229 case R.id.animateY: { 230 chart.animateY(2000); 231 break; 232 } 233 case R.id.animateXY: { 234 235 chart.animateXY(2000, 2000); 236 break; 237 } 238 case R.id.actionSave: { 239 if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { 240 saveToGallery(); 241 } else { 242 requestStoragePermission(chart); 243 } 244 break; 245 } 246 } 247 return true; 248 } 249 250 @Override saveToGallery()251 protected void saveToGallery() { 252 saveToGallery(chart, "StackedBarActivity"); 253 } 254 255 @Override onStartTrackingTouch(SeekBar seekBar)256 public void onStartTrackingTouch(SeekBar seekBar) {} 257 258 @Override onStopTrackingTouch(SeekBar seekBar)259 public void onStopTrackingTouch(SeekBar seekBar) {} 260 261 @Override onValueSelected(Entry e, Highlight h)262 public void onValueSelected(Entry e, Highlight h) { 263 264 BarEntry entry = (BarEntry) e; 265 266 if (entry.getYVals() != null) 267 Log.i("VAL SELECTED", "Value: " + entry.getYVals()[h.getStackIndex()]); 268 else 269 Log.i("VAL SELECTED", "Value: " + entry.getY()); 270 } 271 272 @Override onNothingSelected()273 public void onNothingSelected() {} 274 getColors()275 private int[] getColors() { 276 277 // have as many colors as stack-values per entry 278 int[] colors = new int[3]; 279 280 System.arraycopy(ColorTemplate.MATERIAL_COLORS, 0, colors, 0, 3); 281 282 return colors; 283 } 284 } 285