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.net.Uri; 9 import android.os.Bundle; 10 import androidx.core.content.ContextCompat; 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.XAxis; 20 import com.github.mikephil.charting.components.YAxis; 21 import com.github.mikephil.charting.data.Entry; 22 import com.github.mikephil.charting.data.LineData; 23 import com.github.mikephil.charting.data.LineDataSet; 24 import com.github.mikephil.charting.formatter.IFillFormatter; 25 import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider; 26 import com.github.mikephil.charting.interfaces.datasets.IDataSet; 27 import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; 28 import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase; 29 30 import java.util.ArrayList; 31 import java.util.List; 32 33 public class CubicLineChartActivity extends DemoBase implements OnSeekBarChangeListener { 34 35 private LineChart chart; 36 private SeekBar seekBarX, seekBarY; 37 private TextView tvX, tvY; 38 39 @Override onCreate(Bundle savedInstanceState)40 protected void onCreate(Bundle savedInstanceState) { 41 super.onCreate(savedInstanceState); 42 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, 43 WindowManager.LayoutParams.FLAG_FULLSCREEN); 44 setContentView(R.layout.activity_linechart); 45 46 setTitle("CubicLineChartActivity"); 47 48 tvX = findViewById(R.id.tvXMax); 49 tvY = findViewById(R.id.tvYMax); 50 51 seekBarX = findViewById(R.id.seekBar1); 52 seekBarY = findViewById(R.id.seekBar2); 53 54 chart = findViewById(R.id.chart1); 55 chart.setViewPortOffsets(0, 0, 0, 0); 56 chart.setBackgroundColor(Color.rgb(104, 241, 175)); 57 58 // no description text 59 chart.getDescription().setEnabled(false); 60 61 // enable touch gestures 62 chart.setTouchEnabled(true); 63 64 // enable scaling and dragging 65 chart.setDragEnabled(true); 66 chart.setScaleEnabled(true); 67 68 // if disabled, scaling can be done on x- and y-axis separately 69 chart.setPinchZoom(false); 70 71 chart.setDrawGridBackground(false); 72 chart.setMaxHighlightDistance(300); 73 74 XAxis x = chart.getXAxis(); 75 x.setEnabled(false); 76 77 YAxis y = chart.getAxisLeft(); 78 y.setTypeface(tfLight); 79 y.setLabelCount(6, false); 80 y.setTextColor(Color.WHITE); 81 y.setPosition(YAxis.YAxisLabelPosition.INSIDE_CHART); 82 y.setDrawGridLines(false); 83 y.setAxisLineColor(Color.WHITE); 84 85 chart.getAxisRight().setEnabled(false); 86 87 // add data 88 seekBarY.setOnSeekBarChangeListener(this); 89 seekBarX.setOnSeekBarChangeListener(this); 90 91 // lower max, as cubic runs significantly slower than linear 92 seekBarX.setMax(700); 93 94 seekBarX.setProgress(45); 95 seekBarY.setProgress(100); 96 97 chart.getLegend().setEnabled(false); 98 99 chart.animateXY(2000, 2000); 100 101 // don't forget to refresh the drawing 102 chart.invalidate(); 103 } 104 setData(int count, float range)105 private void setData(int count, float range) { 106 107 ArrayList<Entry> values = new ArrayList<>(); 108 109 for (int i = 0; i < count; i++) { 110 float val = (float) (Math.random() * (range + 1)) + 20; 111 values.add(new Entry(i, val)); 112 } 113 114 LineDataSet set1; 115 116 if (chart.getData() != null && 117 chart.getData().getDataSetCount() > 0) { 118 set1 = (LineDataSet) chart.getData().getDataSetByIndex(0); 119 set1.setValues(values); 120 chart.getData().notifyDataChanged(); 121 chart.notifyDataSetChanged(); 122 } else { 123 // create a dataset and give it a type 124 set1 = new LineDataSet(values, "DataSet 1"); 125 126 set1.setMode(LineDataSet.Mode.CUBIC_BEZIER); 127 set1.setCubicIntensity(0.2f); 128 set1.setDrawFilled(true); 129 set1.setDrawCircles(false); 130 set1.setLineWidth(1.8f); 131 set1.setCircleRadius(4f); 132 set1.setCircleColor(Color.WHITE); 133 set1.setHighLightColor(Color.rgb(244, 117, 117)); 134 set1.setColor(Color.WHITE); 135 set1.setFillColor(Color.WHITE); 136 set1.setFillAlpha(100); 137 set1.setDrawHorizontalHighlightIndicator(false); 138 set1.setFillFormatter(new IFillFormatter() { 139 @Override 140 public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) { 141 return chart.getAxisLeft().getAxisMinimum(); 142 } 143 }); 144 145 // create a data object with the data sets 146 LineData data = new LineData(set1); 147 data.setValueTypeface(tfLight); 148 data.setValueTextSize(9f); 149 data.setDrawValues(false); 150 151 // set data 152 chart.setData(data); 153 } 154 } 155 156 @Override onCreateOptionsMenu(Menu menu)157 public boolean onCreateOptionsMenu(Menu menu) { 158 getMenuInflater().inflate(R.menu.line, menu); 159 return true; 160 } 161 162 @Override onOptionsItemSelected(MenuItem item)163 public boolean onOptionsItemSelected(MenuItem item) { 164 165 switch (item.getItemId()) { 166 case R.id.viewGithub: { 167 Intent i = new Intent(Intent.ACTION_VIEW); 168 i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CubicLineChartActivity.java")); 169 startActivity(i); 170 break; 171 } 172 case R.id.actionToggleValues: { 173 for (IDataSet set : chart.getData().getDataSets()) 174 set.setDrawValues(!set.isDrawValuesEnabled()); 175 176 chart.invalidate(); 177 break; 178 } 179 case R.id.actionToggleHighlight: { 180 if(chart.getData() != null) { 181 chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled()); 182 chart.invalidate(); 183 } 184 break; 185 } 186 case R.id.actionToggleFilled: { 187 188 List<ILineDataSet> sets = chart.getData() 189 .getDataSets(); 190 191 for (ILineDataSet iSet : sets) { 192 193 LineDataSet set = (LineDataSet) iSet; 194 195 if (set.isDrawFilledEnabled()) 196 set.setDrawFilled(false); 197 else 198 set.setDrawFilled(true); 199 } 200 chart.invalidate(); 201 break; 202 } 203 case R.id.actionToggleCircles: { 204 List<ILineDataSet> sets = chart.getData() 205 .getDataSets(); 206 207 for (ILineDataSet iSet : sets) { 208 209 LineDataSet set = (LineDataSet) iSet; 210 if (set.isDrawCirclesEnabled()) 211 set.setDrawCircles(false); 212 else 213 set.setDrawCircles(true); 214 } 215 chart.invalidate(); 216 break; 217 } 218 case R.id.actionToggleCubic: { 219 List<ILineDataSet> sets = chart.getData() 220 .getDataSets(); 221 222 for (ILineDataSet iSet : sets) { 223 224 LineDataSet set = (LineDataSet) iSet; 225 set.setMode(set.getMode() == LineDataSet.Mode.CUBIC_BEZIER 226 ? LineDataSet.Mode.LINEAR 227 : LineDataSet.Mode.CUBIC_BEZIER); 228 } 229 chart.invalidate(); 230 break; 231 } 232 case R.id.actionToggleStepped: { 233 List<ILineDataSet> sets = chart.getData() 234 .getDataSets(); 235 236 for (ILineDataSet iSet : sets) { 237 238 LineDataSet set = (LineDataSet) iSet; 239 set.setMode(set.getMode() == LineDataSet.Mode.STEPPED 240 ? LineDataSet.Mode.LINEAR 241 : LineDataSet.Mode.STEPPED); 242 } 243 chart.invalidate(); 244 break; 245 } 246 case R.id.actionToggleHorizontalCubic: { 247 List<ILineDataSet> sets = chart.getData() 248 .getDataSets(); 249 250 for (ILineDataSet iSet : sets) { 251 252 LineDataSet set = (LineDataSet) iSet; 253 set.setMode(set.getMode() == LineDataSet.Mode.HORIZONTAL_BEZIER 254 ? LineDataSet.Mode.LINEAR 255 : LineDataSet.Mode.HORIZONTAL_BEZIER); 256 } 257 chart.invalidate(); 258 break; 259 } 260 case R.id.actionTogglePinch: { 261 if (chart.isPinchZoomEnabled()) 262 chart.setPinchZoom(false); 263 else 264 chart.setPinchZoom(true); 265 266 chart.invalidate(); 267 break; 268 } 269 case R.id.actionToggleAutoScaleMinMax: { 270 chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled()); 271 chart.notifyDataSetChanged(); 272 break; 273 } 274 case R.id.animateX: { 275 chart.animateX(2000); 276 break; 277 } 278 case R.id.animateY: { 279 chart.animateY(2000); 280 break; 281 } 282 case R.id.animateXY: { 283 chart.animateXY(2000, 2000); 284 break; 285 } 286 case R.id.actionSave: { 287 if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) { 288 saveToGallery(); 289 } else { 290 requestStoragePermission(chart); 291 } 292 break; 293 } 294 } 295 return true; 296 } 297 298 @Override onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)299 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { 300 301 tvX.setText(String.valueOf(seekBarX.getProgress())); 302 tvY.setText(String.valueOf(seekBarY.getProgress())); 303 304 setData(seekBarX.getProgress(), seekBarY.getProgress()); 305 306 // redraw 307 chart.invalidate(); 308 } 309 310 @Override saveToGallery()311 protected void saveToGallery() { 312 saveToGallery(chart, "CubicLineChartActivity"); 313 } 314 315 @Override onStartTrackingTouch(SeekBar seekBar)316 public void onStartTrackingTouch(SeekBar seekBar) {} 317 318 @Override onStopTrackingTouch(SeekBar seekBar)319 public void onStopTrackingTouch(SeekBar seekBar) {} 320 } 321