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.RectF; 8 import android.net.Uri; 9 import android.os.Bundle; 10 import androidx.core.content.ContextCompat; 11 import android.util.Log; 12 import android.view.Menu; 13 import android.view.MenuItem; 14 import android.view.WindowManager; 15 import android.widget.SeekBar; 16 import android.widget.SeekBar.OnSeekBarChangeListener; 17 import android.widget.TextView; 18 19 import com.github.mikephil.charting.charts.HorizontalBarChart; 20 import com.github.mikephil.charting.components.Legend; 21 import com.github.mikephil.charting.components.XAxis; 22 import com.github.mikephil.charting.components.XAxis.XAxisPosition; 23 import com.github.mikephil.charting.components.YAxis; 24 import com.github.mikephil.charting.data.BarData; 25 import com.github.mikephil.charting.data.BarDataSet; 26 import com.github.mikephil.charting.data.BarEntry; 27 import com.github.mikephil.charting.data.Entry; 28 import com.github.mikephil.charting.highlight.Highlight; 29 import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; 30 import com.github.mikephil.charting.listener.OnChartValueSelectedListener; 31 import com.github.mikephil.charting.utils.MPPointF; 32 import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase; 33 34 import java.util.ArrayList; 35 import java.util.List; 36 37 public class HorizontalBarChartActivity extends DemoBase implements OnSeekBarChangeListener, 38 OnChartValueSelectedListener { 39 40 private HorizontalBarChart 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, 48 WindowManager.LayoutParams.FLAG_FULLSCREEN); 49 setContentView(R.layout.activity_horizontalbarchart); 50 51 setTitle("HorizontalBarChartActivity"); 52 53 tvX = findViewById(R.id.tvXMax); 54 tvY = findViewById(R.id.tvYMax); 55 56 seekBarX = findViewById(R.id.seekBar1); 57 seekBarY = findViewById(R.id.seekBar2); 58 59 seekBarY.setOnSeekBarChangeListener(this); 60 seekBarX.setOnSeekBarChangeListener(this); 61 62 chart = findViewById(R.id.chart1); 63 chart.setOnChartValueSelectedListener(this); 64 // chart.setHighlightEnabled(false); 65 66 chart.setDrawBarShadow(false); 67 68 chart.setDrawValueAboveBar(true); 69 70 chart.getDescription().setEnabled(false); 71 72 // if more than 60 entries are displayed in the chart, no values will be 73 // drawn 74 chart.setMaxVisibleValueCount(60); 75 76 // scaling can now only be done on x- and y-axis separately 77 chart.setPinchZoom(false); 78 79 // draw shadows for each bar that show the maximum value 80 // chart.setDrawBarShadow(true); 81 82 chart.setDrawGridBackground(false); 83 84 XAxis xl = chart.getXAxis(); 85 xl.setPosition(XAxisPosition.BOTTOM); 86 xl.setTypeface(tfLight); 87 xl.setDrawAxisLine(true); 88 xl.setDrawGridLines(false); 89 xl.setGranularity(10f); 90 91 YAxis yl = chart.getAxisLeft(); 92 yl.setTypeface(tfLight); 93 yl.setDrawAxisLine(true); 94 yl.setDrawGridLines(true); 95 yl.setAxisMinimum(0f); // this replaces setStartAtZero(true) 96 // yl.setInverted(true); 97 98 YAxis yr = chart.getAxisRight(); 99 yr.setTypeface(tfLight); 100 yr.setDrawAxisLine(true); 101 yr.setDrawGridLines(false); 102 yr.setAxisMinimum(0f); // this replaces setStartAtZero(true) 103 // yr.setInverted(true); 104 105 chart.setFitBars(true); 106 chart.animateY(2500); 107 108 // setting data 109 seekBarY.setProgress(50); 110 seekBarX.setProgress(12); 111 112 Legend l = chart.getLegend(); 113 l.setVerticalAlignment(Legend.LegendVerticalAlignment.BOTTOM); 114 l.setHorizontalAlignment(Legend.LegendHorizontalAlignment.LEFT); 115 l.setOrientation(Legend.LegendOrientation.HORIZONTAL); 116 l.setDrawInside(false); 117 l.setFormSize(8f); 118 l.setXEntrySpace(4f); 119 } 120 setData(int count, float range)121 private void setData(int count, float range) { 122 123 float barWidth = 9f; 124 float spaceForBar = 10f; 125 ArrayList<BarEntry> values = new ArrayList<>(); 126 127 for (int i = 0; i < count; i++) { 128 float val = (float) (Math.random() * range); 129 values.add(new BarEntry(i * spaceForBar, val, 130 getResources().getDrawable(R.drawable.star))); 131 } 132 133 BarDataSet set1; 134 135 if (chart.getData() != null && 136 chart.getData().getDataSetCount() > 0) { 137 set1 = (BarDataSet) chart.getData().getDataSetByIndex(0); 138 set1.setValues(values); 139 chart.getData().notifyDataChanged(); 140 chart.notifyDataSetChanged(); 141 } else { 142 set1 = new BarDataSet(values, "DataSet 1"); 143 144 set1.setDrawIcons(false); 145 146 ArrayList<IBarDataSet> dataSets = new ArrayList<>(); 147 dataSets.add(set1); 148 149 BarData data = new BarData(dataSets); 150 data.setValueTextSize(10f); 151 data.setValueTypeface(tfLight); 152 data.setBarWidth(barWidth); 153 chart.setData(data); 154 } 155 } 156 157 @Override onCreateOptionsMenu(Menu menu)158 public boolean onCreateOptionsMenu(Menu menu) { 159 getMenuInflater().inflate(R.menu.bar, menu); 160 return true; 161 } 162 163 @Override onOptionsItemSelected(MenuItem item)164 public boolean onOptionsItemSelected(MenuItem item) { 165 166 switch (item.getItemId()) { 167 case R.id.viewGithub: { 168 Intent i = new Intent(Intent.ACTION_VIEW); 169 i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/HorizontalBarChartActivity.java")); 170 startActivity(i); 171 break; 172 } 173 case R.id.actionToggleValues: { 174 List<IBarDataSet> sets = chart.getData() 175 .getDataSets(); 176 177 for (IBarDataSet iSet : sets) { 178 iSet.setDrawValues(!iSet.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 iSet.setDrawIcons(!iSet.isDrawIconsEnabled()); 190 } 191 192 chart.invalidate(); 193 break; 194 } 195 case R.id.actionToggleHighlight: { 196 if(chart.getData() != null) { 197 chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled()); 198 chart.invalidate(); 199 } 200 break; 201 } 202 case R.id.actionTogglePinch: { 203 if (chart.isPinchZoomEnabled()) 204 chart.setPinchZoom(false); 205 else 206 chart.setPinchZoom(true); 207 208 chart.invalidate(); 209 break; 210 } 211 case R.id.actionToggleAutoScaleMinMax: { 212 chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled()); 213 chart.notifyDataSetChanged(); 214 break; 215 } 216 case R.id.actionToggleBarBorders: { 217 for (IBarDataSet set : chart.getData().getDataSets()) 218 ((BarDataSet)set).setBarBorderWidth(set.getBarBorderWidth() == 1.f ? 0.f : 1.f); 219 220 chart.invalidate(); 221 break; 222 } 223 case R.id.animateX: { 224 chart.animateX(2000); 225 break; 226 } 227 case R.id.animateY: { 228 chart.animateY(2000); 229 break; 230 } 231 case R.id.animateXY: { 232 chart.animateXY(2000, 2000); 233 break; 234 } 235 case R.id.actionSave: { 236 if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { 237 saveToGallery(); 238 } else { 239 requestStoragePermission(chart); 240 } 241 break; 242 } 243 } 244 return true; 245 } 246 247 @Override onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)248 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 249 250 tvX.setText(String.valueOf(seekBarX.getProgress())); 251 tvY.setText(String.valueOf(seekBarY.getProgress())); 252 253 setData(seekBarX.getProgress(), seekBarY.getProgress()); 254 chart.setFitBars(true); 255 chart.invalidate(); 256 } 257 258 @Override saveToGallery()259 protected void saveToGallery() { 260 saveToGallery(chart, "HorizontalBarChartActivity"); 261 } 262 263 @Override onStartTrackingTouch(SeekBar seekBar)264 public void onStartTrackingTouch(SeekBar seekBar) {} 265 266 @Override onStopTrackingTouch(SeekBar seekBar)267 public void onStopTrackingTouch(SeekBar seekBar) {} 268 269 private final RectF mOnValueSelectedRectF = new RectF(); 270 271 @Override onValueSelected(Entry e, Highlight h)272 public void onValueSelected(Entry e, Highlight h) { 273 274 if (e == null) 275 return; 276 277 RectF bounds = mOnValueSelectedRectF; 278 chart.getBarBounds((BarEntry) e, bounds); 279 280 MPPointF position = chart.getPosition(e, chart.getData().getDataSetByIndex(h.getDataSetIndex()) 281 .getAxisDependency()); 282 283 Log.i("bounds", bounds.toString()); 284 Log.i("position", position.toString()); 285 286 MPPointF.recycleInstance(position); 287 } 288 289 @Override onNothingSelected()290 public void onNothingSelected() {} 291 } 292