diff --git a/MPChartExample/AndroidManifest.xml b/MPChartExample/AndroidManifest.xml index ef5edb5338..cd08251e3f 100644 --- a/MPChartExample/AndroidManifest.xml +++ b/MPChartExample/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="29" + android:versionName="1.7.4" > - + + diff --git a/MPChartExample/build.gradle b/MPChartExample/build.gradle index 8a33f7e0cf..31e0a5f1a3 100644 --- a/MPChartExample/build.gradle +++ b/MPChartExample/build.gradle @@ -7,8 +7,8 @@ android { applicationId 'com.xxmassdeveloper.mpchartexample' minSdkVersion 16 targetSdkVersion 19 - versionCode 28 - versionName '1.7.1' + versionCode 29 + versionName '1.7.4' sourceSets { main { diff --git a/MPChartExample/libs/mpandroidchartlibrary-1-7-4.jar b/MPChartExample/libs/mpandroidchartlibrary-1-7-4.jar new file mode 100644 index 0000000000..749ac46032 Binary files /dev/null and b/MPChartExample/libs/mpandroidchartlibrary-1-7-4.jar differ diff --git a/MPChartExample/project.properties b/MPChartExample/project.properties index a8d309b24e..4ab125693c 100644 --- a/MPChartExample/project.properties +++ b/MPChartExample/project.properties @@ -12,4 +12,3 @@ # Project target. target=android-19 -android.library.reference.1=../MPChartLib diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity1.java similarity index 99% rename from MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity.java rename to MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity1.java index 9cf0ad6700..395f33e645 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity1.java @@ -31,7 +31,7 @@ import java.util.ArrayList; -public class LineChartActivity extends DemoBase implements OnSeekBarChangeListener, +public class LineChartActivity1 extends DemoBase implements OnSeekBarChangeListener, OnChartGestureListener, OnChartValueSelectedListener { private LineChart mChart; diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity2.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity2.java new file mode 100644 index 0000000000..1c0b942373 --- /dev/null +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartActivity2.java @@ -0,0 +1,328 @@ + +package com.xxmassdeveloper.mpchartexample; + +import android.graphics.Color; +import android.graphics.Typeface; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuItem; +import android.view.WindowManager; +import android.widget.SeekBar; +import android.widget.SeekBar.OnSeekBarChangeListener; +import android.widget.TextView; +import android.widget.Toast; + +import com.github.mikephil.charting.charts.BarLineChartBase.BorderPosition; +import com.github.mikephil.charting.charts.LineChart; +import com.github.mikephil.charting.data.Entry; +import com.github.mikephil.charting.data.LineData; +import com.github.mikephil.charting.data.LineDataSet; +import com.github.mikephil.charting.data.filter.Approximator; +import com.github.mikephil.charting.data.filter.Approximator.ApproximatorType; +import com.github.mikephil.charting.interfaces.OnChartValueSelectedListener; +import com.github.mikephil.charting.utils.ColorTemplate; +import com.github.mikephil.charting.utils.Legend; +import com.github.mikephil.charting.utils.Legend.LegendForm; +import com.github.mikephil.charting.utils.XLabels; +import com.github.mikephil.charting.utils.YLabels; +import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase; + +import java.util.ArrayList; + +public class LineChartActivity2 extends DemoBase implements OnSeekBarChangeListener, + OnChartValueSelectedListener { + + private LineChart mChart; + private SeekBar mSeekBarX, mSeekBarY; + private TextView tvX, tvY; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + setContentView(R.layout.activity_linechart); + + tvX = (TextView) findViewById(R.id.tvXMax); + tvY = (TextView) findViewById(R.id.tvYMax); + mSeekBarX = (SeekBar) findViewById(R.id.seekBar1); + mSeekBarY = (SeekBar) findViewById(R.id.seekBar2); + + mSeekBarX.setProgress(45); + mSeekBarY.setProgress(100); + + mSeekBarY.setOnSeekBarChangeListener(this); + mSeekBarX.setOnSeekBarChangeListener(this); + + mChart = (LineChart) findViewById(R.id.chart1); + mChart.setOnChartValueSelectedListener(this); + + mChart.setUnit(" $"); + mChart.setDrawUnitsInChart(true); + + // if enabled, the chart will always start at zero on the y-axis + mChart.setStartAtZero(false); + + // disable the drawing of values into the chart + mChart.setDrawYValues(false); + + mChart.setDrawBorder(true); + mChart.setBorderPositions(new BorderPosition[] { + BorderPosition.BOTTOM + }); + + // no description text + mChart.setDescription(""); + mChart.setNoDataTextDescription("You need to provide data for the chart."); + + // enable value highlighting + mChart.setHighlightEnabled(true); + + // enable touch gestures + mChart.setTouchEnabled(true); + + // enable scaling and dragging + mChart.setDragEnabled(true); + mChart.setScaleEnabled(true); + mChart.setDrawGridBackground(false); + mChart.setDrawVerticalGrid(false); + mChart.setDrawHorizontalGrid(false); + + // if disabled, scaling can be done on x- and y-axis separately + mChart.setPinchZoom(true); + + // set an alternative background color + mChart.setBackgroundColor(Color.GRAY); + + // add data + setData(45, 100); + + mChart.animateX(2500); + + Typeface tf = Typeface.createFromAsset(getAssets(), "OpenSans-Regular.ttf"); + + // get the legend (only possible after setting data) + Legend l = mChart.getLegend(); + + // modify the legend ... + // l.setPosition(LegendPosition.LEFT_OF_CHART); + l.setForm(LegendForm.LINE); + l.setTypeface(tf); + l.setTextColor(Color.WHITE); + + XLabels xl = mChart.getXLabels(); + xl.setTypeface(tf); + xl.setTextColor(Color.WHITE); + + YLabels yl = mChart.getYLabels(); + yl.setTypeface(tf); + yl.setTextColor(Color.WHITE); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.line, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + + switch (item.getItemId()) { + case R.id.actionToggleValues: { + if (mChart.isDrawYValuesEnabled()) + mChart.setDrawYValues(false); + else + mChart.setDrawYValues(true); + mChart.invalidate(); + break; + } + case R.id.actionToggleHighlight: { + if (mChart.isHighlightEnabled()) + mChart.setHighlightEnabled(false); + else + mChart.setHighlightEnabled(true); + mChart.invalidate(); + break; + } + case R.id.actionToggleFilled: { + + ArrayList sets = (ArrayList) mChart.getData() + .getDataSets(); + + for (LineDataSet set : sets) { + if (set.isDrawFilledEnabled()) + set.setDrawFilled(false); + else + set.setDrawFilled(true); + } + mChart.invalidate(); + break; + } + case R.id.actionToggleCircles: { + ArrayList sets = (ArrayList) mChart.getData() + .getDataSets(); + + for (LineDataSet set : sets) { + if (set.isDrawCirclesEnabled()) + set.setDrawCircles(false); + else + set.setDrawCircles(true); + } + mChart.invalidate(); + break; + } + case R.id.actionToggleCubic: { + ArrayList sets = (ArrayList) mChart.getData() + .getDataSets(); + + for (LineDataSet set : sets) { + if (set.isDrawCubicEnabled()) + set.setDrawCubic(false); + else + set.setDrawCubic(true); + } + mChart.invalidate(); + break; + } + case R.id.actionToggleStartzero: { + if (mChart.isStartAtZeroEnabled()) + mChart.setStartAtZero(false); + else + mChart.setStartAtZero(true); + + mChart.invalidate(); + break; + } + case R.id.actionTogglePinch: { + if (mChart.isPinchZoomEnabled()) + mChart.setPinchZoom(false); + else + mChart.setPinchZoom(true); + + mChart.invalidate(); + break; + } + case R.id.animateX: { + mChart.animateX(3000); + break; + } + case R.id.animateY: { + mChart.animateY(3000); + break; + } + case R.id.animateXY: { + mChart.animateXY(3000, 3000); + break; + } + case R.id.actionToggleAdjustXLegend: { + XLabels xLabels = mChart.getXLabels(); + + if (xLabels.isAdjustXLabelsEnabled()) + xLabels.setAdjustXLabels(false); + else + xLabels.setAdjustXLabels(true); + + mChart.invalidate(); + break; + } + case R.id.actionToggleFilter: { + + // the angle of filtering is 35° + Approximator a = new Approximator(ApproximatorType.DOUGLAS_PEUCKER, 35); + + if (!mChart.isFilteringEnabled()) { + mChart.enableFiltering(a); + } else { + mChart.disableFiltering(); + } + mChart.invalidate(); + break; + } + case R.id.actionSave: { + if (mChart.saveToPath("title" + System.currentTimeMillis(), "")) { + Toast.makeText(getApplicationContext(), "Saving SUCCESSFUL!", + Toast.LENGTH_SHORT).show(); + } else + Toast.makeText(getApplicationContext(), "Saving FAILED!", Toast.LENGTH_SHORT) + .show(); + + // mChart.saveToGallery("title"+System.currentTimeMillis()) + break; + } + } + return true; + } + + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + + tvX.setText("" + (mSeekBarX.getProgress() + 1)); + tvY.setText("" + (mSeekBarY.getProgress())); + + setData(mSeekBarX.getProgress() + 1, mSeekBarY.getProgress()); + + // redraw + mChart.invalidate(); + } + + private void setData(int count, float range) { + + ArrayList xVals = new ArrayList(); + for (int i = 0; i < count; i++) { + xVals.add((i) + ""); + } + + ArrayList yVals = new ArrayList(); + + for (int i = 0; i < count; i++) { + float mult = (range + 1); + float val = (float) (Math.random() * mult) + 3;// + (float) + // ((mult * + // 0.1) / 10); + yVals.add(new Entry(val, i)); + } + + // create a dataset and give it a type + LineDataSet set1 = new LineDataSet(yVals, "DataSet 1"); + set1.setColor(ColorTemplate.getHoloBlue()); + set1.setCircleColor(ColorTemplate.getHoloBlue()); + set1.setLineWidth(2f); + set1.setCircleSize(4f); + set1.setFillAlpha(65); + set1.setFillColor(ColorTemplate.getHoloBlue()); + set1.setHighLightColor(Color.rgb(244, 117, 117)); + + ArrayList dataSets = new ArrayList(); + dataSets.add(set1); // add the datasets + + // create a data object with the datasets + LineData data = new LineData(xVals, dataSets); + + // set data + mChart.setData(data); + } + + @Override + public void onValueSelected(Entry e, int dataSetIndex) { + Log.i("Entry selected", e.toString()); + } + + @Override + public void onNothingSelected() { + Log.i("Nothing selected", "Nothing selected."); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + // TODO Auto-generated method stub + + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + // TODO Auto-generated method stub + + } +} diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/notimportant/MainActivity.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/notimportant/MainActivity.java index dbe38c8936..6e91dac71e 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/notimportant/MainActivity.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/notimportant/MainActivity.java @@ -27,7 +27,8 @@ import com.xxmassdeveloper.mpchartexample.CubicLineChartActivity; import com.xxmassdeveloper.mpchartexample.DynamicalAddingActivity; import com.xxmassdeveloper.mpchartexample.InvertedLineChartActivity; -import com.xxmassdeveloper.mpchartexample.LineChartActivity; +import com.xxmassdeveloper.mpchartexample.LineChartActivity1; +import com.xxmassdeveloper.mpchartexample.LineChartActivity2; import com.xxmassdeveloper.mpchartexample.LineChartActivityColored; import com.xxmassdeveloper.mpchartexample.ListViewBarChartActivity; import com.xxmassdeveloper.mpchartexample.ListViewMultiChartActivity; @@ -56,7 +57,8 @@ protected void onCreate(Bundle savedInstanceState) { ArrayList objects = new ArrayList(); - objects.add(new ContentItem("Line Chart", "A simple demonstration of the linechart.")); + objects.add(new ContentItem("Line Chart 1", "A simple demonstration of the linechart.")); + objects.add(new ContentItem("Line Chart 2", "Another simple demonstration of the linechart.")); objects.add(new ContentItem("Bar Chart", "A simple demonstration of the bar chart.")); objects.add(new ContentItem("Pie Chart", "A simple demonstration of the pie chart.")); objects.add(new ContentItem("Scatter Chart", "A simple demonstration of the scatter chart.")); @@ -113,39 +115,42 @@ public void onItemClick(AdapterView av, View v, int pos, long arg3) { switch (pos) { case 0: - i = new Intent(this, LineChartActivity.class); + i = new Intent(this, LineChartActivity1.class); startActivity(i); break; case 1: - i = new Intent(this, BarChartActivity.class); + i = new Intent(this, LineChartActivity2.class); startActivity(i); break; case 2: - i = new Intent(this, PieChartActivity.class); + i = new Intent(this, BarChartActivity.class); startActivity(i); break; case 3: - i = new Intent(this, ScatterChartActivity.class); + i = new Intent(this, PieChartActivity.class); startActivity(i); break; case 4: - i = new Intent(this, StackedBarActivity.class); + i = new Intent(this, ScatterChartActivity.class); startActivity(i); break; case 5: - i = new Intent(this, AnotherBarActivity.class); + i = new Intent(this, StackedBarActivity.class); startActivity(i); break; case 6: - i = new Intent(this, MultiLineChartActivity.class); + i = new Intent(this, AnotherBarActivity.class); startActivity(i); - break; case 7: - i = new Intent(this, BarChartActivityMultiDataset.class); + i = new Intent(this, MultiLineChartActivity.class); startActivity(i); break; case 8: + i = new Intent(this, BarChartActivityMultiDataset.class); + startActivity(i); + break; + case 9: // i = new Intent(this, DrawChartActivity.class); // startActivity(i); @@ -155,39 +160,39 @@ public void onItemClick(AdapterView av, View v, int pos, long arg3) { b.setPositiveButton("OK", null); b.create().show(); break; - case 9: + case 10: i = new Intent(this, SimpleChartDemo.class); startActivity(i); break; - case 10: + case 11: i = new Intent(this, ListViewBarChartActivity.class); startActivity(i); break; - case 11: + case 12: i = new Intent(this, ListViewMultiChartActivity.class); startActivity(i); break; - case 12: + case 13: i = new Intent(this, InvertedLineChartActivity.class); startActivity(i); break; - case 13: + case 14: i = new Intent(this, CandleStickChartActivity.class); startActivity(i); break; - case 14: + case 15: i = new Intent(this, CubicLineChartActivity.class); startActivity(i); break; - case 15: + case 16: i = new Intent(this, RadarChartActivitry.class); startActivity(i); break; - case 16: + case 17: i = new Intent(this, LineChartActivityColored.class); startActivity(i); break; - case 17: + case 18: i = new Intent(this, DynamicalAddingActivity.class); startActivity(i); break; diff --git a/MPChartLib/src/com/github/mikephil/charting/charts/BarLineChartBase.java b/MPChartLib/src/com/github/mikephil/charting/charts/BarLineChartBase.java index ee7c6ff0de..5c8c6fae70 100644 --- a/MPChartLib/src/com/github/mikephil/charting/charts/BarLineChartBase.java +++ b/MPChartLib/src/com/github/mikephil/charting/charts/BarLineChartBase.java @@ -775,6 +775,9 @@ protected void drawBorder() { for (int i = 0; i < mBorderPositions.length; i++) { + if (mBorderPositions[i] == null) + continue; + switch (mBorderPositions[i]) { case LEFT: mDrawCanvas.drawLine(mOffsetLeft, mOffsetTop, mOffsetLeft, getHeight() @@ -1452,6 +1455,24 @@ public BorderPosition[] getBorderPositions() { return mBorderPositions; } + /** + * Sets the width of the border surrounding the chart in dp. + * + * @param width + */ + public void setBorderWidth(int width) { + mBorderPaint.setStrokeWidth(Utils.convertDpToPixel(width)); + } + + /** + * Sets the color of the border surrounding the chart. + * + * @param color + */ + public void setBorderColor(int color) { + mBorderPaint.setColor(color); + } + /** * Returns the Highlight object (contains x-index and DataSet index) of the * selected value at the given touch point inside the Line-, Scatter-, or diff --git a/MPChartLib/src/com/github/mikephil/charting/charts/RadarChart.java b/MPChartLib/src/com/github/mikephil/charting/charts/RadarChart.java index d933ba3bc0..0d93fa88e5 100644 --- a/MPChartLib/src/com/github/mikephil/charting/charts/RadarChart.java +++ b/MPChartLib/src/com/github/mikephil/charting/charts/RadarChart.java @@ -92,7 +92,15 @@ protected void init() { protected void calcMinMax(boolean fixedValues) { super.calcMinMax(fixedValues); + // additional handling for space (default 15% space) + // float space = Math.abs(mDeltaY / 100f * 15f); + + if (mYChartMax <= 0) + mYChartMax = 1f; + mYChartMin = 0; + + mDeltaY = Math.abs(mYChartMax - mYChartMin); } @Override @@ -103,7 +111,6 @@ public void prepare() { prepareXLabels(); } - @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); @@ -291,7 +298,9 @@ private void drawLimitLines() { private void prepareYLabels() { int labelCount = mYLabels.getLabelCount(); - double range = mData.getYMax() - mYChartMin; + + double max = mData.getYMax() > 0 ? mData.getYMax() : 1.0; + double range = max - mYChartMin; double rawInterval = range / labelCount; double interval = Utils.roundToNextSignificant(rawInterval); @@ -304,7 +313,7 @@ private void prepareYLabels() { } double first = Math.ceil(mYChartMin / interval) * interval; - double last = Utils.nextUp(Math.floor(mData.getYMax() / interval) * interval); + double last = Utils.nextUp(Math.floor(max / interval) * interval); double f; int n = 0; @@ -640,7 +649,7 @@ public boolean isDrawXLabelsEnabled() { protected float getRequiredBottomOffset() { return mLegendLabelPaint.getTextSize() * 6.5f; } - + @Override protected float getRequiredBaseOffset() { return mXLabels.mLabelWidth; diff --git a/MPChartLib/src/com/github/mikephil/charting/utils/Utils.java b/MPChartLib/src/com/github/mikephil/charting/utils/Utils.java index 204a305dab..991fc7734a 100644 --- a/MPChartLib/src/com/github/mikephil/charting/utils/Utils.java +++ b/MPChartLib/src/com/github/mikephil/charting/utils/Utils.java @@ -336,7 +336,7 @@ public static String[] convertStrings(ArrayList strings) { /** * Replacement for the Math.nextUp(...) method that is only available in - * HONEYCOMB and higher. + * HONEYCOMB and higher. Dat's some seeeeek sheeet. * * @param d * @return