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.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.LineChart; 19 import com.github.mikephil.charting.components.Legend; 20 import com.github.mikephil.charting.components.Legend.LegendForm; 21 import com.github.mikephil.charting.components.XAxis; 22 import com.github.mikephil.charting.components.YAxis; 23 import com.github.mikephil.charting.data.Entry; 24 import com.github.mikephil.charting.data.LineData; 25 import com.github.mikephil.charting.data.LineDataSet; 26 import com.github.mikephil.charting.highlight.Highlight; 27 import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; 28 import com.github.mikephil.charting.listener.OnChartValueSelectedListener; 29 import com.github.mikephil.charting.utils.EntryXComparator; 30 import com.xxmassdeveloper.mpchartexample.custom.MyMarkerView; 31 import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase; 32 33 import java.util.ArrayList; 34 import java.util.Collections; 35 import java.util.List; 36 37 public class InvertedLineChartActivity extends DemoBase implements OnSeekBarChangeListener, 38 OnChartValueSelectedListener { 39 40 private LineChart 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_linechart); 50 51 setTitle("InvertedLineChartActivity"); 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.setDrawGridBackground(false); 65 66 // no description text 67 chart.getDescription().setEnabled(false); 68 69 // enable touch gestures 70 chart.setTouchEnabled(true); 71 72 // enable scaling and dragging 73 chart.setDragEnabled(true); 74 chart.setScaleEnabled(true); 75 76 // if disabled, scaling can be done on x- and y-axis separately 77 chart.setPinchZoom(true); 78 79 // set an alternative background color 80 // chart.setBackgroundColor(Color.GRAY); 81 82 // create a custom MarkerView (extend MarkerView) and specify the layout 83 // to use for it 84 MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view); 85 mv.setChartView(chart); // For bounds control 86 chart.setMarker(mv); // Set the marker to the chart 87 88 XAxis xl = chart.getXAxis(); 89 xl.setAvoidFirstLastClipping(true); 90 xl.setAxisMinimum(0f); 91 92 YAxis leftAxis = chart.getAxisLeft(); 93 leftAxis.setInverted(true); 94 leftAxis.setAxisMinimum(0f); // this replaces setStartAtZero(true) 95 96 YAxis rightAxis = chart.getAxisRight(); 97 rightAxis.setEnabled(false); 98 99 // add data 100 seekBarX.setProgress(25); 101 seekBarY.setProgress(50); 102 103 // // restrain the maximum scale-out factor 104 // chart.setScaleMinima(3f, 3f); 105 // 106 // // center the view to a specific position inside the chart 107 // chart.centerViewPort(10, 50); 108 109 // get the legend (only possible after setting data) 110 Legend l = chart.getLegend(); 111 112 // modify the legend ... 113 l.setForm(LegendForm.LINE); 114 115 // don't forget to refresh the drawing 116 chart.invalidate(); 117 } 118 setData(int count, float range)119 private void setData(int count, float range) { 120 121 ArrayList<Entry> entries = new ArrayList<>(); 122 123 for (int i = 0; i < count; i++) { 124 float xVal = (float) (Math.random() * range); 125 float yVal = (float) (Math.random() * range); 126 entries.add(new Entry(xVal, yVal)); 127 } 128 129 // sort by x-value 130 Collections.sort(entries, new EntryXComparator()); 131 132 // create a dataset and give it a type 133 LineDataSet set1 = new LineDataSet(entries, "DataSet 1"); 134 135 set1.setLineWidth(1.5f); 136 set1.setCircleRadius(4f); 137 138 // create a data object with the data sets 139 LineData data = new LineData(set1); 140 141 // set data 142 chart.setData(data); 143 } 144 145 @Override onCreateOptionsMenu(Menu menu)146 public boolean onCreateOptionsMenu(Menu menu) { 147 getMenuInflater().inflate(R.menu.line, menu); 148 return true; 149 } 150 151 @Override onOptionsItemSelected(MenuItem item)152 public boolean onOptionsItemSelected(MenuItem item) { 153 154 switch (item.getItemId()) { 155 case R.id.viewGithub: { 156 Intent i = new Intent(Intent.ACTION_VIEW); 157 i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/InvertedLineChartActivity.java")); 158 startActivity(i); 159 break; 160 } 161 case R.id.actionToggleValues: { 162 List<ILineDataSet> sets = chart.getData() 163 .getDataSets(); 164 165 for (ILineDataSet iSet : sets) { 166 167 LineDataSet set = (LineDataSet) iSet; 168 set.setDrawValues(!set.isDrawValuesEnabled()); 169 } 170 171 chart.invalidate(); 172 break; 173 } 174 case R.id.actionToggleHighlight: { 175 if(chart.getData() != null) { 176 chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled()); 177 chart.invalidate(); 178 } 179 break; 180 } 181 case R.id.actionToggleFilled: { 182 183 List<ILineDataSet> sets = chart.getData() 184 .getDataSets(); 185 186 for (ILineDataSet iSet : sets) { 187 188 LineDataSet set = (LineDataSet) iSet; 189 if (set.isDrawFilledEnabled()) 190 set.setDrawFilled(false); 191 else 192 set.setDrawFilled(true); 193 } 194 chart.invalidate(); 195 break; 196 } 197 case R.id.actionToggleCircles: { 198 List<ILineDataSet> sets = chart.getData() 199 .getDataSets(); 200 201 for (ILineDataSet iSet : sets) { 202 203 LineDataSet set = (LineDataSet) iSet; 204 if (set.isDrawCirclesEnabled()) 205 set.setDrawCircles(false); 206 else 207 set.setDrawCircles(true); 208 } 209 chart.invalidate(); 210 break; 211 } 212 case R.id.animateX: { 213 chart.animateX(2000); 214 break; 215 } 216 case R.id.animateY: { 217 chart.animateY(2000); 218 break; 219 } 220 case R.id.animateXY: { 221 222 chart.animateXY(2000, 2000); 223 break; 224 } 225 case R.id.actionTogglePinch: { 226 if (chart.isPinchZoomEnabled()) 227 chart.setPinchZoom(false); 228 else 229 chart.setPinchZoom(true); 230 231 chart.invalidate(); 232 break; 233 } 234 case R.id.actionToggleAutoScaleMinMax: { 235 chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled()); 236 chart.notifyDataSetChanged(); 237 break; 238 } 239 case R.id.actionSave: { 240 if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { 241 saveToGallery(); 242 } else { 243 requestStoragePermission(chart); 244 } 245 break; 246 } 247 } 248 return true; 249 } 250 251 @Override onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)252 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 253 254 tvX.setText(String.valueOf(seekBarX.getProgress())); 255 tvY.setText(String.valueOf(seekBarY.getProgress())); 256 257 setData(seekBarX.getProgress(), seekBarY.getProgress()); 258 259 // redraw 260 chart.invalidate(); 261 } 262 263 @Override saveToGallery()264 protected void saveToGallery() { 265 saveToGallery(chart, "InvertedLineChartActivity"); 266 } 267 268 @Override onValueSelected(Entry e, Highlight h)269 public void onValueSelected(Entry e, Highlight h) { 270 Log.i("VAL SELECTED", 271 "Value: " + e.getY() + ", xIndex: " + e.getX() 272 + ", DataSet index: " + h.getDataSetIndex()); 273 } 274 275 @Override onNothingSelected()276 public void onNothingSelected() {} 277 278 @Override onStartTrackingTouch(SeekBar seekBar)279 public void onStartTrackingTouch(SeekBar seekBar) {} 280 281 @Override onStopTrackingTouch(SeekBar seekBar)282 public void onStopTrackingTouch(SeekBar seekBar) {} 283 } 284