• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.graphics.DashPathEffect;
9 import android.graphics.drawable.Drawable;
10 import android.net.Uri;
11 import android.os.Bundle;
12 import androidx.core.content.ContextCompat;
13 import android.util.Log;
14 import android.view.Menu;
15 import android.view.MenuItem;
16 import android.view.WindowManager;
17 import android.widget.SeekBar;
18 import android.widget.SeekBar.OnSeekBarChangeListener;
19 import android.widget.TextView;
20 
21 import com.github.mikephil.charting.animation.Easing;
22 import com.github.mikephil.charting.charts.LineChart;
23 import com.github.mikephil.charting.components.Legend;
24 import com.github.mikephil.charting.components.Legend.LegendForm;
25 import com.github.mikephil.charting.components.LimitLine;
26 import com.github.mikephil.charting.components.LimitLine.LimitLabelPosition;
27 import com.github.mikephil.charting.components.XAxis;
28 import com.github.mikephil.charting.components.YAxis;
29 import com.github.mikephil.charting.data.Entry;
30 import com.github.mikephil.charting.data.LineData;
31 import com.github.mikephil.charting.data.LineDataSet;
32 import com.github.mikephil.charting.formatter.IFillFormatter;
33 import com.github.mikephil.charting.highlight.Highlight;
34 import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider;
35 import com.github.mikephil.charting.interfaces.datasets.ILineDataSet;
36 import com.github.mikephil.charting.listener.OnChartValueSelectedListener;
37 import com.github.mikephil.charting.utils.Utils;
38 import com.xxmassdeveloper.mpchartexample.custom.MyMarkerView;
39 import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase;
40 
41 import java.util.ArrayList;
42 import java.util.List;
43 
44 /**
45  * Example of a heavily customized {@link LineChart} with limit lines, custom line shapes, etc.
46  *
47  * @since 1.7.4
48  * @version 3.1.0
49  */
50 public class LineChartActivity1 extends DemoBase implements OnSeekBarChangeListener,
51         OnChartValueSelectedListener {
52 
53     private LineChart chart;
54     private SeekBar seekBarX, seekBarY;
55     private TextView tvX, tvY;
56 
57     @Override
onCreate(Bundle savedInstanceState)58     protected void onCreate(Bundle savedInstanceState) {
59         super.onCreate(savedInstanceState);
60         getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
61                 WindowManager.LayoutParams.FLAG_FULLSCREEN);
62         setContentView(R.layout.activity_linechart);
63 
64         setTitle("LineChartActivity1");
65 
66         tvX = findViewById(R.id.tvXMax);
67         tvY = findViewById(R.id.tvYMax);
68 
69         seekBarX = findViewById(R.id.seekBar1);
70         seekBarX.setOnSeekBarChangeListener(this);
71 
72         seekBarY = findViewById(R.id.seekBar2);
73         seekBarY.setMax(180);
74         seekBarY.setOnSeekBarChangeListener(this);
75 
76 
77         {   // // Chart Style // //
78             chart = findViewById(R.id.chart1);
79 
80             // background color
81             chart.setBackgroundColor(Color.WHITE);
82 
83             // disable description text
84             chart.getDescription().setEnabled(false);
85 
86             // enable touch gestures
87             chart.setTouchEnabled(true);
88 
89             // set listeners
90             chart.setOnChartValueSelectedListener(this);
91             chart.setDrawGridBackground(false);
92 
93             // create marker to display box when values are selected
94             MyMarkerView mv = new MyMarkerView(this, R.layout.custom_marker_view);
95 
96             // Set the marker to the chart
97             mv.setChartView(chart);
98             chart.setMarker(mv);
99 
100             // enable scaling and dragging
101             chart.setDragEnabled(true);
102             chart.setScaleEnabled(true);
103             // chart.setScaleXEnabled(true);
104             // chart.setScaleYEnabled(true);
105 
106             // force pinch zoom along both axis
107             chart.setPinchZoom(true);
108         }
109 
110         XAxis xAxis;
111         {   // // X-Axis Style // //
112             xAxis = chart.getXAxis();
113 
114             // vertical grid lines
115             xAxis.enableGridDashedLine(10f, 10f, 0f);
116         }
117 
118         YAxis yAxis;
119         {   // // Y-Axis Style // //
120             yAxis = chart.getAxisLeft();
121 
122             // disable dual axis (only use LEFT axis)
123             chart.getAxisRight().setEnabled(false);
124 
125             // horizontal grid lines
126             yAxis.enableGridDashedLine(10f, 10f, 0f);
127 
128             // axis range
129             yAxis.setAxisMaximum(200f);
130             yAxis.setAxisMinimum(-50f);
131         }
132 
133 
134         {   // // Create Limit Lines // //
135             LimitLine llXAxis = new LimitLine(9f, "Index 10");
136             llXAxis.setLineWidth(4f);
137             llXAxis.enableDashedLine(10f, 10f, 0f);
138             llXAxis.setLabelPosition(LimitLabelPosition.RIGHT_BOTTOM);
139             llXAxis.setTextSize(10f);
140             llXAxis.setTypeface(tfRegular);
141 
142             LimitLine ll1 = new LimitLine(150f, "Upper Limit");
143             ll1.setLineWidth(4f);
144             ll1.enableDashedLine(10f, 10f, 0f);
145             ll1.setLabelPosition(LimitLabelPosition.RIGHT_TOP);
146             ll1.setTextSize(10f);
147             ll1.setTypeface(tfRegular);
148 
149             LimitLine ll2 = new LimitLine(-30f, "Lower Limit");
150             ll2.setLineWidth(4f);
151             ll2.enableDashedLine(10f, 10f, 0f);
152             ll2.setLabelPosition(LimitLabelPosition.RIGHT_BOTTOM);
153             ll2.setTextSize(10f);
154             ll2.setTypeface(tfRegular);
155 
156             // draw limit lines behind data instead of on top
157             yAxis.setDrawLimitLinesBehindData(true);
158             xAxis.setDrawLimitLinesBehindData(true);
159 
160             // add limit lines
161             yAxis.addLimitLine(ll1);
162             yAxis.addLimitLine(ll2);
163             //xAxis.addLimitLine(llXAxis);
164         }
165 
166         // add data
167         seekBarX.setProgress(45);
168         seekBarY.setProgress(180);
169         setData(45, 180);
170 
171         // draw points over time
172         chart.animateX(1500);
173 
174         // get the legend (only possible after setting data)
175         Legend l = chart.getLegend();
176 
177         // draw legend entries as lines
178         l.setForm(LegendForm.LINE);
179     }
180 
setData(int count, float range)181     private void setData(int count, float range) {
182 
183         ArrayList<Entry> values = new ArrayList<>();
184 
185         for (int i = 0; i < count; i++) {
186 
187             float val = (float) (Math.random() * range) - 30;
188             values.add(new Entry(i, val, getResources().getDrawable(R.drawable.star)));
189         }
190 
191         LineDataSet set1;
192 
193         if (chart.getData() != null &&
194                 chart.getData().getDataSetCount() > 0) {
195             set1 = (LineDataSet) chart.getData().getDataSetByIndex(0);
196             set1.setValues(values);
197             set1.notifyDataSetChanged();
198             chart.getData().notifyDataChanged();
199             chart.notifyDataSetChanged();
200         } else {
201             // create a dataset and give it a type
202             set1 = new LineDataSet(values, "DataSet 1");
203 
204             set1.setDrawIcons(false);
205 
206             // draw dashed line
207             set1.enableDashedLine(10f, 5f, 0f);
208 
209             // black lines and points
210             set1.setColor(Color.BLACK);
211             set1.setCircleColor(Color.BLACK);
212 
213             // line thickness and point size
214             set1.setLineWidth(1f);
215             set1.setCircleRadius(3f);
216 
217             // draw points as solid circles
218             set1.setDrawCircleHole(false);
219 
220             // customize legend entry
221             set1.setFormLineWidth(1f);
222             set1.setFormLineDashEffect(new DashPathEffect(new float[]{10f, 5f}, 0f));
223             set1.setFormSize(15.f);
224 
225             // text size of values
226             set1.setValueTextSize(9f);
227 
228             // draw selection line as dashed
229             set1.enableDashedHighlightLine(10f, 5f, 0f);
230 
231             // set the filled area
232             set1.setDrawFilled(true);
233             set1.setFillFormatter(new IFillFormatter() {
234                 @Override
235                 public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
236                     return chart.getAxisLeft().getAxisMinimum();
237                 }
238             });
239 
240             // set color of filled area
241             if (Utils.getSDKInt() >= 18) {
242                 // drawables only supported on api level 18 and above
243                 Drawable drawable = ContextCompat.getDrawable(this, R.drawable.fade_red);
244                 set1.setFillDrawable(drawable);
245             } else {
246                 set1.setFillColor(Color.BLACK);
247             }
248 
249             ArrayList<ILineDataSet> dataSets = new ArrayList<>();
250             dataSets.add(set1); // add the data sets
251 
252             // create a data object with the data sets
253             LineData data = new LineData(dataSets);
254 
255             // set data
256             chart.setData(data);
257         }
258     }
259 
260     @Override
onCreateOptionsMenu(Menu menu)261     public boolean onCreateOptionsMenu(Menu menu) {
262         getMenuInflater().inflate(R.menu.line, menu);
263         return true;
264     }
265 
266     @Override
onOptionsItemSelected(MenuItem item)267     public boolean onOptionsItemSelected(MenuItem item) {
268 
269         switch (item.getItemId()) {
270             case R.id.viewGithub: {
271                 Intent i = new Intent(Intent.ACTION_VIEW);
272                 i.setData(Uri.parse("https://github.com/PhilJay/MPAndroidChart/blob/master/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity1.java"));
273                 startActivity(i);
274                 break;
275             }
276             case R.id.actionToggleValues: {
277                 List<ILineDataSet> sets = chart.getData()
278                         .getDataSets();
279 
280                 for (ILineDataSet iSet : sets) {
281 
282                     LineDataSet set = (LineDataSet) iSet;
283                     set.setDrawValues(!set.isDrawValuesEnabled());
284                 }
285 
286                 chart.invalidate();
287                 break;
288             }
289             case R.id.actionToggleIcons: {
290                 List<ILineDataSet> sets = chart.getData()
291                         .getDataSets();
292 
293                 for (ILineDataSet iSet : sets) {
294 
295                     LineDataSet set = (LineDataSet) iSet;
296                     set.setDrawIcons(!set.isDrawIconsEnabled());
297                 }
298 
299                 chart.invalidate();
300                 break;
301             }
302             case R.id.actionToggleHighlight: {
303                 if(chart.getData() != null) {
304                     chart.getData().setHighlightEnabled(!chart.getData().isHighlightEnabled());
305                     chart.invalidate();
306                 }
307                 break;
308             }
309             case R.id.actionToggleFilled: {
310 
311                 List<ILineDataSet> sets = chart.getData()
312                         .getDataSets();
313 
314                 for (ILineDataSet iSet : sets) {
315 
316                     LineDataSet set = (LineDataSet) iSet;
317                     if (set.isDrawFilledEnabled())
318                         set.setDrawFilled(false);
319                     else
320                         set.setDrawFilled(true);
321                 }
322                 chart.invalidate();
323                 break;
324             }
325             case R.id.actionToggleCircles: {
326                 List<ILineDataSet> sets = chart.getData()
327                         .getDataSets();
328 
329                 for (ILineDataSet iSet : sets) {
330 
331                     LineDataSet set = (LineDataSet) iSet;
332                     if (set.isDrawCirclesEnabled())
333                         set.setDrawCircles(false);
334                     else
335                         set.setDrawCircles(true);
336                 }
337                 chart.invalidate();
338                 break;
339             }
340             case R.id.actionToggleCubic: {
341                 List<ILineDataSet> sets = chart.getData()
342                         .getDataSets();
343 
344                 for (ILineDataSet iSet : sets) {
345 
346                     LineDataSet set = (LineDataSet) iSet;
347                     set.setMode(set.getMode() == LineDataSet.Mode.CUBIC_BEZIER
348                             ? LineDataSet.Mode.LINEAR
349                             :  LineDataSet.Mode.CUBIC_BEZIER);
350                 }
351                 chart.invalidate();
352                 break;
353             }
354             case R.id.actionToggleStepped: {
355                 List<ILineDataSet> sets = chart.getData()
356                         .getDataSets();
357 
358                 for (ILineDataSet iSet : sets) {
359 
360                     LineDataSet set = (LineDataSet) iSet;
361                     set.setMode(set.getMode() == LineDataSet.Mode.STEPPED
362                             ? LineDataSet.Mode.LINEAR
363                             :  LineDataSet.Mode.STEPPED);
364                 }
365                 chart.invalidate();
366                 break;
367             }
368             case R.id.actionToggleHorizontalCubic: {
369                 List<ILineDataSet> sets = chart.getData()
370                         .getDataSets();
371 
372                 for (ILineDataSet iSet : sets) {
373 
374                     LineDataSet set = (LineDataSet) iSet;
375                     set.setMode(set.getMode() == LineDataSet.Mode.HORIZONTAL_BEZIER
376                             ? LineDataSet.Mode.LINEAR
377                             :  LineDataSet.Mode.HORIZONTAL_BEZIER);
378                 }
379                 chart.invalidate();
380                 break;
381             }
382             case R.id.actionTogglePinch: {
383                 if (chart.isPinchZoomEnabled())
384                     chart.setPinchZoom(false);
385                 else
386                     chart.setPinchZoom(true);
387 
388                 chart.invalidate();
389                 break;
390             }
391             case R.id.actionToggleAutoScaleMinMax: {
392                 chart.setAutoScaleMinMaxEnabled(!chart.isAutoScaleMinMaxEnabled());
393                 chart.notifyDataSetChanged();
394                 break;
395             }
396             case R.id.animateX: {
397                 chart.animateX(2000);
398                 break;
399             }
400             case R.id.animateY: {
401                 chart.animateY(2000, Easing.EaseInCubic);
402                 break;
403             }
404             case R.id.animateXY: {
405                 chart.animateXY(2000, 2000);
406                 break;
407             }
408             case R.id.actionSave: {
409                 if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
410                     saveToGallery();
411                 } else {
412                     requestStoragePermission(chart);
413                 }
414                 break;
415             }
416         }
417         return true;
418     }
419 
420     @Override
onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)421     public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
422 
423         tvX.setText(String.valueOf(seekBarX.getProgress()));
424         tvY.setText(String.valueOf(seekBarY.getProgress()));
425 
426         setData(seekBarX.getProgress(), seekBarY.getProgress());
427 
428         // redraw
429         chart.invalidate();
430     }
431 
432     @Override
saveToGallery()433     protected void saveToGallery() {
434         saveToGallery(chart, "LineChartActivity1");
435     }
436 
437     @Override
onStartTrackingTouch(SeekBar seekBar)438     public void onStartTrackingTouch(SeekBar seekBar) {}
439 
440     @Override
onStopTrackingTouch(SeekBar seekBar)441     public void onStopTrackingTouch(SeekBar seekBar) {}
442 
443     @Override
onValueSelected(Entry e, Highlight h)444     public void onValueSelected(Entry e, Highlight h) {
445         Log.i("Entry selected", e.toString());
446         Log.i("LOW HIGH", "low: " + chart.getLowestVisibleX() + ", high: " + chart.getHighestVisibleX());
447         Log.i("MIN MAX", "xMin: " + chart.getXChartMin() + ", xMax: " + chart.getXChartMax() + ", yMin: " + chart.getYChartMin() + ", yMax: " + chart.getYChartMax());
448     }
449 
450     @Override
onNothingSelected()451     public void onNothingSelected() {
452         Log.i("Nothing selected", "Nothing selected.");
453     }
454 }
455