diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivityMultiDataset.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivityMultiDataset.java index 204dc1fe64..3d93c6d9da 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivityMultiDataset.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivityMultiDataset.java @@ -93,7 +93,7 @@ protected void onCreate(Bundle savedInstanceState) { xAxis.setCenterAxisLabels(true); xAxis.setValueFormatter(new IAxisValueFormatter() { @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { return String.valueOf((int) value); } }); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartPositiveNegative.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartPositiveNegative.java index 7d6bd44896..b1687b93aa 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartPositiveNegative.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartPositiveNegative.java @@ -87,7 +87,7 @@ protected void onCreate(Bundle savedInstanceState) { xAxis.setValueFormatter(new IAxisValueFormatter() { @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { return data.get(Math.min(Math.max((int) value, 0), data.size()-1)).xAxisValue; } }); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CombinedChartActivity.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CombinedChartActivity.java index e4d8fb2e3b..a8c5f86f3f 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CombinedChartActivity.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CombinedChartActivity.java @@ -81,7 +81,7 @@ protected void onCreate(Bundle savedInstanceState) { xAxis.setGranularity(1f); xAxis.setValueFormatter(new IAxisValueFormatter() { @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { return mMonths[(int) value % mMonths.length]; } }); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartTime.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartTime.java index 6bf96f02a7..434a7e926f 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartTime.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/LineChartTime.java @@ -25,7 +25,6 @@ import com.github.mikephil.charting.utils.ColorTemplate; import com.xxmassdeveloper.mpchartexample.notimportant.DemoBase; -import java.sql.Time; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; @@ -95,7 +94,7 @@ protected void onCreate(Bundle savedInstanceState) { private SimpleDateFormat mFormat = new SimpleDateFormat("dd MMM HH:mm"); @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { long millis = TimeUnit.HOURS.toMillis((long) value); return mFormat.format(new Date(millis)); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivity.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivity.java index d354886f6e..607d6fa4b3 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivity.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivity.java @@ -74,7 +74,7 @@ protected void onCreate(Bundle savedInstanceState) { private String[] mActivities = new String[]{"Burger", "Steak", "Salad", "Pasta", "Pizza"}; @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { return mActivities[(int) value % mActivities.length]; } }); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/StackedBarActivityNegative.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/StackedBarActivityNegative.java index c1d64a106b..552d9f9376 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/StackedBarActivityNegative.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/StackedBarActivityNegative.java @@ -12,7 +12,6 @@ import com.github.mikephil.charting.charts.HorizontalBarChart; import com.github.mikephil.charting.components.AxisBase; import com.github.mikephil.charting.components.Legend; -import com.github.mikephil.charting.components.Legend.LegendPosition; import com.github.mikephil.charting.components.XAxis; import com.github.mikephil.charting.components.XAxis.XAxisPosition; import com.github.mikephil.charting.components.YAxis; @@ -20,8 +19,8 @@ import com.github.mikephil.charting.data.BarDataSet; import com.github.mikephil.charting.data.BarEntry; import com.github.mikephil.charting.data.Entry; -import com.github.mikephil.charting.formatter.IValueFormatter; import com.github.mikephil.charting.formatter.IAxisValueFormatter; +import com.github.mikephil.charting.formatter.IValueFormatter; import com.github.mikephil.charting.highlight.Highlight; import com.github.mikephil.charting.interfaces.datasets.IBarDataSet; import com.github.mikephil.charting.listener.OnChartValueSelectedListener; @@ -82,7 +81,7 @@ protected void onCreate(Bundle savedInstanceState) { private DecimalFormat format = new DecimalFormat("###"); @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { return format.format(value) + "-" + format.format(value + 10); } }); @@ -250,7 +249,7 @@ public String getFormattedValue(float value, Entry entry, int dataSetIndex, View // YAxis @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { return mFormat.format(Math.abs(value)) + "m"; } } diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/DayAxisValueFormatter.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/DayAxisValueFormatter.java index b8bc1a41c2..5c4896db47 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/DayAxisValueFormatter.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/DayAxisValueFormatter.java @@ -21,7 +21,7 @@ public DayAxisValueFormatter(BarLineChartBase chart) { } @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { int days = (int) value; diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/MyAxisValueFormatter.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/MyAxisValueFormatter.java index e8456675a9..578e76fb16 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/MyAxisValueFormatter.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/MyAxisValueFormatter.java @@ -15,7 +15,7 @@ public MyAxisValueFormatter() { } @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { return mFormat.format(value) + " $"; } } diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/MyCustomXAxisValueFormatter.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/MyCustomXAxisValueFormatter.java index c66e5d4569..dd78241947 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/MyCustomXAxisValueFormatter.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/MyCustomXAxisValueFormatter.java @@ -22,7 +22,7 @@ public MyCustomXAxisValueFormatter(ViewPortHandler viewPortHandler) { } @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { //Log.i("TRANS", "x: " + viewPortHandler.getTransX() + ", y: " + viewPortHandler.getTransY()); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/XYMarkerView.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/XYMarkerView.java index 0475bdd038..1a7e75a23a 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/XYMarkerView.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/XYMarkerView.java @@ -38,7 +38,8 @@ public XYMarkerView(Context context, IAxisValueFormatter xAxisValueFormatter) { @Override public void refreshContent(Entry e, Highlight highlight) { - tvContent.setText("x: " + xAxisValueFormatter.getFormattedValue(e.getX(), null) + ", y: " + format.format(e.getY())); + tvContent.setText("x: " + xAxisValueFormatter.getFormattedValue( + e.getX(), null, 1, 0) + ", y: " + format.format(e.getY())); super.refreshContent(e, highlight); } diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/YearXAxisFormatter.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/YearXAxisFormatter.java index 34d76c25eb..cdb21fb136 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/YearXAxisFormatter.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/custom/YearXAxisFormatter.java @@ -19,7 +19,7 @@ public YearXAxisFormatter() { } @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { float percent = value / axis.mAxisRange; return mMonths[(int) (mMonths.length * percent)]; diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/realm/RealmWikiExample.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/realm/RealmWikiExample.java index f223be6093..a474c2975e 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/realm/RealmWikiExample.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/realm/RealmWikiExample.java @@ -87,7 +87,7 @@ private void setData() { IAxisValueFormatter formatter = new IAxisValueFormatter() { @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { return results.get((int) value).getPlayerName(); } }; diff --git a/MPChartLib/build.gradle b/MPChartLib/build.gradle index 19c06befb3..7b15c5e78e 100644 --- a/MPChartLib/build.gradle +++ b/MPChartLib/build.gradle @@ -1,8 +1,12 @@ apply plugin: 'com.android.library' apply plugin: 'maven' +apply plugin: 'com.jfrog.artifactory' +apply plugin: 'maven-publish' //apply plugin: 'com.github.dcendents.android-maven' //apply plugin: 'realm-android' +def packageName = 'com.wandera.android' + android { compileSdkVersion 27 buildToolsVersion '27.0.3' @@ -12,7 +16,8 @@ android { minSdkVersion 9 targetSdkVersion 27 versionCode 3 - versionName '3.0.3' + version '3.0.3.9' + archivesBaseName = "MPAndroidChart" } buildTypes { release { @@ -26,6 +31,18 @@ android { testOptions { unitTests.returnDefaultValues = true // this prevents "not mocked" error } + + libraryVariants.all { variant -> + println "variant: " + variant.baseName + variant.outputs.all { output -> + if (outputFile != null && outputFileName.endsWith('.aar')) { + // LibraryVariant object does not have #versionNameSuffix + def suffix = variant.baseName == "debug" ? "-SNAPSHOT" : "" + outputFileName = "${archivesBaseName}-${version}${suffix}.aar" + println "outputFileName: " + outputFileName + } + } + } } repositories { @@ -56,7 +73,7 @@ task sourcesJar(type: Jar) { task javadoc(type: Javadoc) { options.charSet = 'UTF-8' - failOnError false + failOnError false source = android.sourceSets.main.java.sourceFiles classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) } @@ -70,3 +87,25 @@ artifacts { archives sourcesJar archives javadocJar } + +publishing { + repositories { + maven { + credentials { + username "${artifactory_user}" + password "${artifactory_password}" + } + url "${artifactory_contextUrl}/libs-release-local" + } + } + publications { + aar(MavenPublication) { + groupId = packageName + artifactId = archivesBaseName + def targetFile = "$buildDir/outputs/aar/${archivesBaseName}-${version}.aar" + println "publishing: " + targetFile + // Tell maven to prepare the generated "*.aar" file for publishing + artifact(targetFile) + } + } +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/components/AxisBase.java b/MPChartLib/src/main/java/com/github/mikephil/charting/components/AxisBase.java index 3c8028c24b..7f93fd54f7 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/components/AxisBase.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/components/AxisBase.java @@ -142,11 +142,21 @@ public abstract class AxisBase extends ComponentBase { */ public float mAxisMaximum = 0f; + /** + * base value from which the actual one is being calculated + */ + protected float mAxisMaximumBase = 0f; + /** * don't touch this directly, use setter */ public float mAxisMinimum = 0f; + /** + * base value from which the actual one is being calculated + */ + protected float mAxisMinimumBase = 0f; + /** * the total range of values this axis covers */ @@ -486,7 +496,7 @@ public String getFormattedLabel(int index) { if (index < 0 || index >= mEntries.length) return ""; else - return getValueFormatter().getFormattedValue(mEntries[index], this); + return getValueFormatter().getFormattedValue(mEntries[index], this, mEntries.length, index); } /** @@ -684,6 +694,7 @@ public boolean isAxisMinCustom() { public void setAxisMinimum(float min) { mCustomAxisMin = true; mAxisMinimum = min; + mAxisMinimumBase = min; this.mAxisRange = Math.abs(mAxisMaximum - min); } @@ -707,6 +718,7 @@ public void setAxisMinValue(float min) { public void setAxisMaximum(float max) { mCustomAxisMax = true; mAxisMaximum = max; + mAxisMaximumBase = max; this.mAxisRange = Math.abs(max - mAxisMinimum); } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/components/CustomLabelDrawJob.java b/MPChartLib/src/main/java/com/github/mikephil/charting/components/CustomLabelDrawJob.java new file mode 100644 index 0000000000..531e84b4f0 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/components/CustomLabelDrawJob.java @@ -0,0 +1,9 @@ +package com.github.mikephil.charting.components; + +import android.graphics.Canvas; +import android.graphics.Paint; + +public abstract class CustomLabelDrawJob { + + public abstract void drawLabel(Canvas c, String label, float x, float y, Paint paint); +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/components/DrawingCustomizable.java b/MPChartLib/src/main/java/com/github/mikephil/charting/components/DrawingCustomizable.java new file mode 100644 index 0000000000..aa305d603b --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/components/DrawingCustomizable.java @@ -0,0 +1,8 @@ +package com.github.mikephil.charting.components; + +public interface DrawingCustomizable { + + void setCustomLabelDrawJob(CustomLabelDrawJob drawJob); + + CustomLabelDrawJob getCustomLabelDrawJob(); +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/components/LimitLine.java b/MPChartLib/src/main/java/com/github/mikephil/charting/components/LimitLine.java index 8fcdee8fc1..bac94a3f8c 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/components/LimitLine.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/components/LimitLine.java @@ -4,7 +4,6 @@ import android.graphics.Color; import android.graphics.DashPathEffect; import android.graphics.Paint; -import android.graphics.Typeface; import com.github.mikephil.charting.utils.Utils; @@ -12,10 +11,10 @@ * The limit line is an additional feature for all Line-, Bar- and * ScatterCharts. It allows the displaying of an additional line in the chart * that marks a certain maximum / limit on the specified axis (x- or y-axis). - * + * * @author Philipp Jahoda */ -public class LimitLine extends ComponentBase { +public class LimitLine extends ComponentBase implements DrawingCustomizable { /** limit / maximum (the y-value or xIndex) */ private float mLimit = 0f; @@ -43,11 +42,13 @@ public enum LimitLabelPosition { LEFT_TOP, LEFT_BOTTOM, RIGHT_TOP, RIGHT_BOTTOM } + private CustomLabelDrawJob mCustomLabelDrawJob; + /** * Constructor with limit. - * + * * @param limit - the position (the value) on the y-axis (y-value) or x-axis - * (xIndex) where this line should appear + * (xIndex) where this line should appear */ public LimitLine(float limit) { mLimit = limit; @@ -55,9 +56,9 @@ public LimitLine(float limit) { /** * Constructor with limit and label. - * + * * @param limit - the position (the value) on the y-axis (y-value) or x-axis - * (xIndex) where this line should appear + * (xIndex) where this line should appear * @param label - provide "" if no label is required */ public LimitLine(float limit, String label) { @@ -65,9 +66,19 @@ public LimitLine(float limit, String label) { mLabel = label; } + @Override + public void setCustomLabelDrawJob(CustomLabelDrawJob drawJob) { + mCustomLabelDrawJob = drawJob; + } + + @Override + public CustomLabelDrawJob getCustomLabelDrawJob() { + return mCustomLabelDrawJob; + } + /** * Returns the limit that is set for this line. - * + * * @return */ public float getLimit() { @@ -77,7 +88,7 @@ public float getLimit() { /** * set the line width of the chart (min = 0.2f, max = 12f); default 2f NOTE: * thinner line == better performance, thicker line == worse performance - * + * * @param width */ public void setLineWidth(float width) { @@ -91,7 +102,7 @@ public void setLineWidth(float width) { /** * returns the width of limit line - * + * * @return */ public float getLineWidth() { @@ -101,7 +112,7 @@ public float getLineWidth() { /** * Sets the linecolor for this LimitLine. Make sure to use * getResources().getColor(...) - * + * * @param color */ public void setLineColor(int color) { @@ -110,7 +121,7 @@ public void setLineColor(int color) { /** * Returns the color that is used for this LimitLine - * + * * @return */ public int getLineColor() { @@ -119,13 +130,13 @@ public int getLineColor() { /** * Enables the line to be drawn in dashed mode, e.g. like this "- - - - - -" - * + * * @param lineLength the length of the line pieces * @param spaceLength the length of space inbetween the pieces * @param phase offset, in degrees (normally, use 0) */ public void enableDashedLine(float lineLength, float spaceLength, float phase) { - mDashPathEffect = new DashPathEffect(new float[] { + mDashPathEffect = new DashPathEffect(new float[]{ lineLength, spaceLength }, phase); } @@ -140,7 +151,7 @@ public void disableDashedLine() { /** * Returns true if the dashed-line effect is enabled, false if not. Default: * disabled - * + * * @return */ public boolean isDashedLineEnabled() { @@ -149,7 +160,7 @@ public boolean isDashedLineEnabled() { /** * returns the DashPathEffect that is set for this LimitLine - * + * * @return */ public DashPathEffect getDashPathEffect() { @@ -178,7 +189,7 @@ public Paint.Style getTextStyle() { /** * Sets the position of the LimitLine value label (either on the right or on * the left edge of the chart). Not supported for RadarChart. - * + * * @param pos */ public void setLabelPosition(LimitLabelPosition pos) { @@ -187,7 +198,7 @@ public void setLabelPosition(LimitLabelPosition pos) { /** * Returns the position of the LimitLine label (value). - * + * * @return */ public LimitLabelPosition getLabelPosition() { @@ -197,7 +208,7 @@ public LimitLabelPosition getLabelPosition() { /** * Sets the label that is drawn next to the limit line. Provide "" if no * label is required. - * + * * @param label */ public void setLabel(String label) { @@ -206,7 +217,7 @@ public void setLabel(String label) { /** * Returns the label that is drawn next to the limit line. - * + * * @return */ public String getLabel() { diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/components/YAxis.java b/MPChartLib/src/main/java/com/github/mikephil/charting/components/YAxis.java index 2381dbf868..f840f4b87c 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/components/YAxis.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/components/YAxis.java @@ -16,7 +16,7 @@ * * @author Philipp Jahoda */ -public class YAxis extends AxisBase { +public class YAxis extends AxisBase implements DrawingCustomizable { /** * indicates if the bottom y-label entry is drawn or not @@ -48,6 +48,11 @@ public class YAxis extends AxisBase { */ private boolean mUseAutoScaleRestrictionMax = false; + /** + * flag indicating if the 0 on the y Axis should be centered in the middle of the screen of there are no data + */ + private boolean mCenterWhenEmpty = true; + /** * Color of the zero line */ @@ -73,6 +78,18 @@ public class YAxis extends AxisBase { */ private YAxisLabelPosition mPosition = YAxisLabelPosition.OUTSIDE_CHART; + private CustomLabelDrawJob mCustomLabelDrawJob; + + @Override + public void setCustomLabelDrawJob(CustomLabelDrawJob drawJob) { + mCustomLabelDrawJob = drawJob; + } + + @Override + public CustomLabelDrawJob getCustomLabelDrawJob() { + return mCustomLabelDrawJob; + } + /** * enum for the position of the y-labels relative to the chart */ @@ -395,6 +412,22 @@ public void setUseAutoScaleMaxRestriction( boolean isEnabled ) { mUseAutoScaleRestrictionMax = isEnabled; } + /** + * Returns true if the 0 of the y axis will be centered in the middle of the graph when there are no data. + */ + public boolean isCenterWhenEmpty() { + + return mCenterWhenEmpty; + } + + /** + * Sets centering of 0 for y Axis when there are no data as enabled/disabled. Enabled by default. + */ + public void setCenterYWhenEmpty(boolean isEnabled) { + + mCenterWhenEmpty = isEnabled; + } + @Override public void calculate(float dataMin, float dataMax) { @@ -405,17 +438,17 @@ public void calculate(float dataMin, float dataMax) { // if custom, use value as is, else use data value if( mCustomAxisMin ) { if( mUseAutoScaleRestrictionMin ) { - min = Math.min( dataMin, mAxisMinimum ); + min = Math.min(dataMin, mAxisMinimumBase); } else { - min = mAxisMinimum; + min = mAxisMinimumBase; } } if( mCustomAxisMax ) { if( mUseAutoScaleRestrictionMax ) { - max = Math.max( max, mAxisMaximum ); + max = Math.max(max, mAxisMaximumBase); } else { - max = mAxisMaximum; + max = mAxisMaximumBase; } } @@ -423,14 +456,16 @@ public void calculate(float dataMin, float dataMax) { float range = Math.abs(max - min); // in case all values are equal - if (range == 0f) { - max = max + 1f; - min = min - 1f; + if (mCenterWhenEmpty) { + if (range == 0f) { + max = max + 1f; + min = min - 1f; + } } float bottomSpace = range / 100f * getSpaceBottom(); this.mAxisMinimum = (min - bottomSpace); - + float topSpace = range / 100f * getSpaceTop(); this.mAxisMaximum = (max + topSpace); diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultAxisValueFormatter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultAxisValueFormatter.java index 552c150e69..81acda3c3c 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultAxisValueFormatter.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultAxisValueFormatter.java @@ -40,7 +40,7 @@ public DefaultAxisValueFormatter(int digits) { } @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { // avoid memory allocations here (for performance) return mFormat.format(value); } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IAxisValueFormatter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IAxisValueFormatter.java index 51939b5432..e454b8608a 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IAxisValueFormatter.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IAxisValueFormatter.java @@ -19,5 +19,5 @@ public interface IAxisValueFormatter * @param axis the axis the value belongs to * @return */ - String getFormattedValue(float value, AxisBase axis); + String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex); } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IndexAxisValueFormatter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IndexAxisValueFormatter.java index 07349a6a0e..4a600f40a9 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IndexAxisValueFormatter.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IndexAxisValueFormatter.java @@ -2,11 +2,7 @@ package com.github.mikephil.charting.formatter; import com.github.mikephil.charting.components.AxisBase; -import com.github.mikephil.charting.data.Entry; -import com.github.mikephil.charting.utils.ViewPortHandler; -import java.text.DecimalFormat; -import java.util.Arrays; import java.util.Collection; /** @@ -44,7 +40,7 @@ public IndexAxisValueFormatter(Collection values) { setValues(values.toArray(new String[values.size()])); } - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { int index = Math.round(value); if (index < 0 || index >= mValueCount || index != (int)value) diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/LargeValueFormatter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/LargeValueFormatter.java index 211401ad8a..8359c20817 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/LargeValueFormatter.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/LargeValueFormatter.java @@ -49,7 +49,7 @@ public String getFormattedValue(float value, Entry entry, int dataSetIndex, View // IAxisValueFormatter @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { return makePretty(value) + mText; } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/PercentFormatter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/PercentFormatter.java index de8a10255a..536c4d5fe3 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/PercentFormatter.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/PercentFormatter.java @@ -39,7 +39,7 @@ public String getFormattedValue(float value, Entry entry, int dataSetIndex, View // IAxisValueFormatter @Override - public String getFormattedValue(float value, AxisBase axis) { + public String getFormattedValue(float value, AxisBase axis, int valuesTotal, int valueIndex) { return mFormat.format(value) + " %"; } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/AxisRenderer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/AxisRenderer.java index 90528a1359..a1390de353 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/AxisRenderer.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/AxisRenderer.java @@ -187,7 +187,7 @@ protected void computeAxisValues(float min, float max) { interval = (float) range / (float) (labelCount - 1); mAxis.mEntryCount = labelCount; - if (mAxis.mEntries.length < labelCount) { + if (mAxis.mEntries.length != labelCount) { // Ensure stops contains at least numStops elements. mAxis.mEntries = new float[labelCount]; } @@ -222,7 +222,7 @@ protected void computeAxisValues(float min, float max) { mAxis.mEntryCount = n; - if (mAxis.mEntries.length < n) { + if (mAxis.mEntries.length != n) { // Ensure stops contains at least numStops elements. mAxis.mEntries = new float[n]; } @@ -245,7 +245,7 @@ protected void computeAxisValues(float min, float max) { if (mAxis.isCenterAxisLabelsEnabled()) { - if (mAxis.mCenteredEntries.length < n) { + if (mAxis.mCenteredEntries.length != n) { mAxis.mCenteredEntries = new float[n]; } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRenderer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRenderer.java index 8adb56c73a..0002e8b412 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRenderer.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRenderer.java @@ -8,6 +8,7 @@ import android.graphics.Path; import android.graphics.RectF; +import com.github.mikephil.charting.components.CustomLabelDrawJob; import com.github.mikephil.charting.components.LimitLine; import com.github.mikephil.charting.components.XAxis; import com.github.mikephil.charting.components.XAxis.XAxisPosition; @@ -25,6 +26,7 @@ public class XAxisRenderer extends AxisRenderer { protected XAxis mXAxis; public XAxisRenderer(ViewPortHandler viewPortHandler, XAxis xAxis, Transformer trans) { + super(viewPortHandler, trans, xAxis); this.mXAxis = xAxis; @@ -35,6 +37,7 @@ public XAxisRenderer(ViewPortHandler viewPortHandler, XAxis xAxis, Transformer t } protected void setupGridPaint() { + mGridPaint.setColor(mXAxis.getGridColor()); mGridPaint.setStrokeWidth(mXAxis.getGridLineWidth()); mGridPaint.setPathEffect(mXAxis.getGridDashPathEffect()); @@ -69,6 +72,7 @@ public void computeAxis(float min, float max, boolean inverted) { @Override protected void computeAxisValues(float min, float max) { + super.computeAxisValues(min, max); computeSize(); @@ -113,7 +117,7 @@ public void renderAxisLabels(Canvas c) { mAxisLabelPaint.setTextSize(mXAxis.getTextSize()); mAxisLabelPaint.setColor(mXAxis.getTextColor()); - MPPointF pointF = MPPointF.getInstance(0,0); + MPPointF pointF = MPPointF.getInstance(0, 0); if (mXAxis.getPosition() == XAxisPosition.TOP) { pointF.x = 0.5f; pointF.y = 1.0f; @@ -202,7 +206,8 @@ protected void drawLabels(Canvas c, float pos, MPPointF anchor) { if (mViewPortHandler.isInBoundsX(x)) { - String label = mXAxis.getValueFormatter().getFormattedValue(mXAxis.mEntries[i / 2], mXAxis); + String label = mXAxis.getValueFormatter().getFormattedValue( + mXAxis.mEntries[i / 2], mXAxis, mXAxis.mEntries.length, i / 2); if (mXAxis.isAvoidFirstLastClippingEnabled()) { @@ -210,15 +215,22 @@ protected void drawLabels(Canvas c, float pos, MPPointF anchor) { if (i / 2 == mXAxis.mEntryCount - 1 && mXAxis.mEntryCount > 1) { float width = Utils.calcTextWidth(mAxisLabelPaint, label); - if (width > mViewPortHandler.offsetRight() * 2 - && x + width > mViewPortHandler.getChartWidth()) - x -= width / 2; - + float clipSize = Math.max( + width / 2 - mViewPortHandler.offsetRight(), + width / 2 + x - mViewPortHandler.getChartWidth()); + if (clipSize > 0) { + x -= clipSize; + } // avoid clipping of the first } else if (i == 0) { float width = Utils.calcTextWidth(mAxisLabelPaint, label); - x += width / 2; + float clipSize = Math.max( + width / 2 - mViewPortHandler.offsetLeft(), + width / 2 - x); + if (clipSize > 0) { + x += clipSize; + } } } @@ -228,10 +240,13 @@ protected void drawLabels(Canvas c, float pos, MPPointF anchor) { } protected void drawLabel(Canvas c, String formattedLabel, float x, float y, MPPointF anchor, float angleDegrees) { + Utils.drawXAxisValue(c, formattedLabel, x, y, mAxisLabelPaint, anchor, angleDegrees); } + protected Path mRenderGridLinesPath = new Path(); protected float[] mRenderGridLinesBuffer = new float[2]; + @Override public void renderGridLines(Canvas c) { @@ -241,7 +256,7 @@ public void renderGridLines(Canvas c) { int clipRestoreCount = c.save(); c.clipRect(getGridClippingRect()); - if(mRenderGridLinesBuffer.length != mAxis.mEntryCount * 2){ + if (mRenderGridLinesBuffer.length != mAxis.mEntryCount * 2) { mRenderGridLinesBuffer = new float[mXAxis.mEntryCount * 2]; } float[] positions = mRenderGridLinesBuffer; @@ -269,6 +284,7 @@ public void renderGridLines(Canvas c) { protected RectF mGridClippingRect = new RectF(); public RectF getGridClippingRect() { + mGridClippingRect.set(mViewPortHandler.getContentRect()); mGridClippingRect.inset(-mAxis.getGridLineWidth(), 0.f); return mGridClippingRect; @@ -341,6 +357,7 @@ public void renderLimitLines(Canvas c) { private Path mLimitLinePath = new Path(); public void renderLimitLineLine(Canvas c, LimitLine limitLine, float[] position) { + mLimitLineSegmentsBuffer[0] = position[0]; mLimitLineSegmentsBuffer[1] = mViewPortHandler.contentTop(); mLimitLineSegmentsBuffer[2] = position[0]; @@ -359,6 +376,7 @@ public void renderLimitLineLine(Canvas c, LimitLine limitLine, float[] position) } public void renderLimitLineLabel(Canvas c, LimitLine limitLine, float[] position, float yOffset) { + String label = limitLine.getLabel(); // if drawing the limit-value label is enabled @@ -375,26 +393,52 @@ public void renderLimitLineLabel(Canvas c, LimitLine limitLine, float[] position final LimitLine.LimitLabelPosition labelPosition = limitLine.getLabelPosition(); + CustomLabelDrawJob customLabelDrawJob = limitLine.getCustomLabelDrawJob(); + float x; + float y; + if (labelPosition == LimitLine.LimitLabelPosition.RIGHT_TOP) { final float labelLineHeight = Utils.calcTextHeight(mLimitLinePaint, label); mLimitLinePaint.setTextAlign(Align.LEFT); - c.drawText(label, position[0] + xOffset, mViewPortHandler.contentTop() + yOffset + labelLineHeight, - mLimitLinePaint); + x = position[0] + xOffset; + y = mViewPortHandler.contentTop() + yOffset + labelLineHeight; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } else if (labelPosition == LimitLine.LimitLabelPosition.RIGHT_BOTTOM) { mLimitLinePaint.setTextAlign(Align.LEFT); - c.drawText(label, position[0] + xOffset, mViewPortHandler.contentBottom() - yOffset, mLimitLinePaint); + x = position[0] + xOffset; + y = mViewPortHandler.contentBottom() - yOffset; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } else if (labelPosition == LimitLine.LimitLabelPosition.LEFT_TOP) { - mLimitLinePaint.setTextAlign(Align.RIGHT); final float labelLineHeight = Utils.calcTextHeight(mLimitLinePaint, label); - c.drawText(label, position[0] - xOffset, mViewPortHandler.contentTop() + yOffset + labelLineHeight, - mLimitLinePaint); + mLimitLinePaint.setTextAlign(Align.RIGHT); + x = position[0] - xOffset; + y = mViewPortHandler.contentTop() + yOffset + labelLineHeight; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } else { mLimitLinePaint.setTextAlign(Align.RIGHT); - c.drawText(label, position[0] - xOffset, mViewPortHandler.contentBottom() - yOffset, mLimitLinePaint); + x = position[0] - xOffset; + y = mViewPortHandler.contentBottom() - yOffset; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererHorizontalBarChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererHorizontalBarChart.java index 86047cf1b8..9121854289 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererHorizontalBarChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererHorizontalBarChart.java @@ -8,12 +8,13 @@ import android.graphics.RectF; import com.github.mikephil.charting.charts.BarChart; +import com.github.mikephil.charting.components.CustomLabelDrawJob; import com.github.mikephil.charting.components.LimitLine; import com.github.mikephil.charting.components.XAxis; import com.github.mikephil.charting.components.XAxis.XAxisPosition; import com.github.mikephil.charting.utils.FSize; -import com.github.mikephil.charting.utils.MPPointF; import com.github.mikephil.charting.utils.MPPointD; +import com.github.mikephil.charting.utils.MPPointF; import com.github.mikephil.charting.utils.Transformer; import com.github.mikephil.charting.utils.Utils; import com.github.mikephil.charting.utils.ViewPortHandler; @@ -38,7 +39,8 @@ public void computeAxis(float min, float max, boolean inverted) { // zoom / contentrect bounds) if (mViewPortHandler.contentWidth() > 10 && !mViewPortHandler.isFullyZoomedOutY()) { - MPPointD p1 = mTrans.getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentBottom()); + MPPointD p1 = mTrans.getValuesByTouchPoint(mViewPortHandler.contentLeft(), + mViewPortHandler.contentBottom()); MPPointD p2 = mTrans.getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop()); if (inverted) { @@ -57,10 +59,10 @@ public void computeAxis(float min, float max, boolean inverted) { computeAxisValues(min, max); } - + @Override protected void computeSize() { - + mAxisLabelPaint.setTypeface(mXAxis.getTypeface()); mAxisLabelPaint.setTextSize(mXAxis.getTextSize()); @@ -68,7 +70,7 @@ protected void computeSize() { final FSize labelSize = Utils.calcTextSize(mAxisLabelPaint, longest); - final float labelWidth = (int)(labelSize.width + mXAxis.getXOffset() * 3.5f); + final float labelWidth = (int) (labelSize.width + mXAxis.getXOffset() * 3.5f); final float labelHeight = labelSize.height; final FSize labelRotatedSize = Utils.getSizeOfRotatedRectangleByDegrees( @@ -78,7 +80,7 @@ protected void computeSize() { mXAxis.mLabelWidth = Math.round(labelWidth); mXAxis.mLabelHeight = Math.round(labelHeight); - mXAxis.mLabelRotatedWidth = (int)(labelRotatedSize.width + mXAxis.getXOffset() * 3.5f); + mXAxis.mLabelRotatedWidth = (int) (labelRotatedSize.width + mXAxis.getXOffset() * 3.5f); mXAxis.mLabelRotatedHeight = Math.round(labelRotatedSize.height); FSize.recycleInstance(labelRotatedSize); @@ -96,7 +98,7 @@ public void renderAxisLabels(Canvas c) { mAxisLabelPaint.setTextSize(mXAxis.getTextSize()); mAxisLabelPaint.setColor(mXAxis.getTextColor()); - MPPointF pointF = MPPointF.getInstance(0,0); + MPPointF pointF = MPPointF.getInstance(0, 0); if (mXAxis.getPosition() == XAxisPosition.TOP) { pointF.x = 0.0f; @@ -156,7 +158,8 @@ protected void drawLabels(Canvas c, float pos, MPPointF anchor) { if (mViewPortHandler.isInBoundsY(y)) { - String label = mXAxis.getValueFormatter().getFormattedValue(mXAxis.mEntries[i / 2], mXAxis); + String label = mXAxis.getValueFormatter().getFormattedValue( + mXAxis.mEntries[i / 2], mXAxis, mXAxis.mEntries.length, i / 2); drawLabel(c, label, pos, y, anchor, labelRotationAngleDegrees); } } @@ -208,32 +211,33 @@ public void renderAxisLine(Canvas c) { } protected Path mRenderLimitLinesPathBuffer = new Path(); + /** - * Draws the LimitLines associated with this axis to the screen. - * This is the standard YAxis renderer using the XAxis limit lines. - * - * @param c - */ - @Override - public void renderLimitLines(Canvas c) { + * Draws the LimitLines associated with this axis to the screen. + * This is the standard YAxis renderer using the XAxis limit lines. + * + * @param c + */ + @Override + public void renderLimitLines(Canvas c) { - List limitLines = mXAxis.getLimitLines(); + List limitLines = mXAxis.getLimitLines(); - if (limitLines == null || limitLines.size() <= 0) - return; + if (limitLines == null || limitLines.size() <= 0) + return; - float[] pts = mRenderLimitLinesBuffer; + float[] pts = mRenderLimitLinesBuffer; pts[0] = 0; pts[1] = 0; - Path limitLinePath = mRenderLimitLinesPathBuffer; + Path limitLinePath = mRenderLimitLinesPathBuffer; limitLinePath.reset(); - for (int i = 0; i < limitLines.size(); i++) { + for (int i = 0; i < limitLines.size(); i++) { - LimitLine l = limitLines.get(i); + LimitLine l = limitLines.get(i); - if(!l.isEnabled()) + if (!l.isEnabled()) continue; int clipRestoreCount = c.save(); @@ -241,32 +245,32 @@ public void renderLimitLines(Canvas c) { mLimitLineClippingRect.inset(0.f, -l.getLineWidth()); c.clipRect(mLimitLineClippingRect); - mLimitLinePaint.setStyle(Paint.Style.STROKE); - mLimitLinePaint.setColor(l.getLineColor()); - mLimitLinePaint.setStrokeWidth(l.getLineWidth()); - mLimitLinePaint.setPathEffect(l.getDashPathEffect()); + mLimitLinePaint.setStyle(Paint.Style.STROKE); + mLimitLinePaint.setColor(l.getLineColor()); + mLimitLinePaint.setStrokeWidth(l.getLineWidth()); + mLimitLinePaint.setPathEffect(l.getDashPathEffect()); - pts[1] = l.getLimit(); + pts[1] = l.getLimit(); - mTrans.pointValuesToPixel(pts); + mTrans.pointValuesToPixel(pts); - limitLinePath.moveTo(mViewPortHandler.contentLeft(), pts[1]); - limitLinePath.lineTo(mViewPortHandler.contentRight(), pts[1]); + limitLinePath.moveTo(mViewPortHandler.contentLeft(), pts[1]); + limitLinePath.lineTo(mViewPortHandler.contentRight(), pts[1]); - c.drawPath(limitLinePath, mLimitLinePaint); - limitLinePath.reset(); - // c.drawLines(pts, mLimitLinePaint); + c.drawPath(limitLinePath, mLimitLinePaint); + limitLinePath.reset(); + // c.drawLines(pts, mLimitLinePaint); - String label = l.getLabel(); + String label = l.getLabel(); - // if drawing the limit-value label is enabled - if (label != null && !label.equals("")) { + // if drawing the limit-value label is enabled + if (label != null && !label.equals("")) { - mLimitLinePaint.setStyle(l.getTextStyle()); - mLimitLinePaint.setPathEffect(null); - mLimitLinePaint.setColor(l.getTextColor()); - mLimitLinePaint.setStrokeWidth(0.5f); - mLimitLinePaint.setTextSize(l.getTextSize()); + mLimitLinePaint.setStyle(l.getTextStyle()); + mLimitLinePaint.setPathEffect(null); + mLimitLinePaint.setColor(l.getTextColor()); + mLimitLinePaint.setStrokeWidth(0.5f); + mLimitLinePaint.setTextSize(l.getTextSize()); final float labelLineHeight = Utils.calcTextHeight(mLimitLinePaint, label); float xOffset = Utils.convertDpToPixel(4f) + l.getXOffset(); @@ -274,37 +278,57 @@ public void renderLimitLines(Canvas c) { final LimitLine.LimitLabelPosition position = l.getLabelPosition(); - if (position == LimitLine.LimitLabelPosition.RIGHT_TOP) { + CustomLabelDrawJob customLabelDrawJob = l.getCustomLabelDrawJob(); + float x; + float y; - mLimitLinePaint.setTextAlign(Align.RIGHT); - c.drawText(label, - mViewPortHandler.contentRight() - xOffset, - pts[1] - yOffset + labelLineHeight, mLimitLinePaint); + if (position == LimitLine.LimitLabelPosition.RIGHT_TOP) { - } else if (position == LimitLine.LimitLabelPosition.RIGHT_BOTTOM) { + mLimitLinePaint.setTextAlign(Align.RIGHT); + x = mViewPortHandler.contentRight() - xOffset; + y = pts[1] - yOffset + labelLineHeight; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } + + } else if (position == LimitLine.LimitLabelPosition.RIGHT_BOTTOM) { mLimitLinePaint.setTextAlign(Align.RIGHT); - c.drawText(label, - mViewPortHandler.contentRight() - xOffset, - pts[1] + yOffset, mLimitLinePaint); + x = mViewPortHandler.contentRight() - xOffset; + y = pts[1] + yOffset; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } else if (position == LimitLine.LimitLabelPosition.LEFT_TOP) { mLimitLinePaint.setTextAlign(Align.LEFT); - c.drawText(label, - mViewPortHandler.contentLeft() + xOffset, - pts[1] - yOffset + labelLineHeight, mLimitLinePaint); + x = mViewPortHandler.contentLeft() + xOffset; + y = pts[1] - yOffset + labelLineHeight; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } else { - mLimitLinePaint.setTextAlign(Align.LEFT); - c.drawText(label, - mViewPortHandler.offsetLeft() + xOffset, - pts[1] + yOffset, mLimitLinePaint); - } - } + mLimitLinePaint.setTextAlign(Align.LEFT); + x = mViewPortHandler.offsetLeft() + xOffset; + y = pts[1] + yOffset; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } + } + } c.restoreToCount(clipRestoreCount); - } - } + } + } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererRadarChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererRadarChart.java index 956e8c7d5c..9eecf450e0 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererRadarChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererRadarChart.java @@ -2,7 +2,6 @@ package com.github.mikephil.charting.renderer; import android.graphics.Canvas; -import android.graphics.PointF; import com.github.mikephil.charting.charts.RadarChart; import com.github.mikephil.charting.components.XAxis; @@ -43,7 +42,8 @@ public void renderAxisLabels(Canvas c) { MPPointF pOut = MPPointF.getInstance(0,0); for (int i = 0; i < mChart.getData().getMaxEntryCountSet().getEntryCount(); i++) { - String label = mXAxis.getValueFormatter().getFormattedValue(i, mXAxis); + String label = mXAxis.getValueFormatter().getFormattedValue( + i, mXAxis, mChart.getData().getMaxEntryCountSet().getEntryCount(), i); float angle = (sliceangle * i + mChart.getRotationAngle()) % 360f; diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRenderer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRenderer.java index a2bf679777..2745a4c0cc 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRenderer.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRenderer.java @@ -7,6 +7,7 @@ import android.graphics.Path; import android.graphics.RectF; +import com.github.mikephil.charting.components.CustomLabelDrawJob; import com.github.mikephil.charting.components.LimitLine; import com.github.mikephil.charting.components.YAxis; import com.github.mikephil.charting.components.YAxis.AxisDependency; @@ -29,7 +30,7 @@ public YAxisRenderer(ViewPortHandler viewPortHandler, YAxis yAxis, Transformer t this.mYAxis = yAxis; - if(mViewPortHandler != null) { + if (mViewPortHandler != null) { mAxisLabelPaint.setColor(Color.BLACK); mAxisLabelPaint.setTextSize(Utils.convertDpToPixel(10f)); @@ -123,12 +124,18 @@ protected void drawYLabels(Canvas c, float fixedPosition, float[] positions, flo for (int i = from; i < to; i++) { String text = mYAxis.getFormattedLabel(i); + CustomLabelDrawJob customLabelDrawJob = mYAxis.getCustomLabelDrawJob(); - c.drawText(text, fixedPosition, positions[i * 2 + 1] + offset, mAxisLabelPaint); + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, text, fixedPosition, positions[i * 2 + 1] + offset, mAxisLabelPaint); + } else { + c.drawText(text, fixedPosition, positions[i * 2 + 1] + offset, mAxisLabelPaint); + } } } protected Path mRenderGridLinesPath = new Path(); + @Override public void renderGridLines(Canvas c) { @@ -190,6 +197,7 @@ protected Path linePath(Path p, int i, float[] positions) { } protected float[] mGetTransformedPositionsBuffer = new float[2]; + /** * Transforms the values contained in the axis entries to screen pixels and returns them in form of a float array * of x- and y-coordinates. @@ -198,7 +206,7 @@ protected Path linePath(Path p, int i, float[] positions) { */ protected float[] getTransformedPositions() { - if(mGetTransformedPositionsBuffer.length != mYAxis.mEntryCount * 2){ + if (mGetTransformedPositionsBuffer.length != mYAxis.mEntryCount * 2) { mGetTransformedPositionsBuffer = new float[mYAxis.mEntryCount * 2]; } float[] positions = mGetTransformedPositionsBuffer; @@ -246,6 +254,7 @@ protected void drawZeroLine(Canvas c) { protected Path mRenderLimitLines = new Path(); protected float[] mRenderLimitLinesBuffer = new float[2]; protected RectF mLimitLineClippingRect = new RectF(); + /** * Draws the LimitLines associated with this axis to the screen. * @@ -311,33 +320,50 @@ public void renderLimitLines(Canvas c) { final LimitLine.LimitLabelPosition position = l.getLabelPosition(); + CustomLabelDrawJob customLabelDrawJob = l.getCustomLabelDrawJob(); + float x; + float y; + if (position == LimitLine.LimitLabelPosition.RIGHT_TOP) { mLimitLinePaint.setTextAlign(Align.RIGHT); - c.drawText(label, - mViewPortHandler.contentRight() - xOffset, - pts[1] - yOffset + labelLineHeight, mLimitLinePaint); - + x = mViewPortHandler.contentRight() - xOffset; + y = pts[1] - yOffset + labelLineHeight; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } else if (position == LimitLine.LimitLabelPosition.RIGHT_BOTTOM) { mLimitLinePaint.setTextAlign(Align.RIGHT); - c.drawText(label, - mViewPortHandler.contentRight() - xOffset, - pts[1] + yOffset, mLimitLinePaint); - + x = mViewPortHandler.contentRight() - xOffset; + y = pts[1] + yOffset; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } else if (position == LimitLine.LimitLabelPosition.LEFT_TOP) { mLimitLinePaint.setTextAlign(Align.LEFT); - c.drawText(label, - mViewPortHandler.contentLeft() + xOffset, - pts[1] - yOffset + labelLineHeight, mLimitLinePaint); - + x = mViewPortHandler.contentLeft() + xOffset; + y = pts[1] - yOffset + labelLineHeight; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } else { mLimitLinePaint.setTextAlign(Align.LEFT); - c.drawText(label, - mViewPortHandler.offsetLeft() + xOffset, - pts[1] + yOffset, mLimitLinePaint); + x = mViewPortHandler.offsetLeft() + xOffset; + y = pts[1] + yOffset; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRendererHorizontalBarChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRendererHorizontalBarChart.java index 71275b03c3..b5ed2e6642 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRendererHorizontalBarChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRendererHorizontalBarChart.java @@ -7,6 +7,7 @@ import android.graphics.Path; import android.graphics.RectF; +import com.github.mikephil.charting.components.CustomLabelDrawJob; import com.github.mikephil.charting.components.LimitLine; import com.github.mikephil.charting.components.YAxis; import com.github.mikephil.charting.components.YAxis.AxisDependency; @@ -21,7 +22,7 @@ public class YAxisRendererHorizontalBarChart extends YAxisRenderer { public YAxisRendererHorizontalBarChart(ViewPortHandler viewPortHandler, YAxis yAxis, - Transformer trans) { + Transformer trans) { super(viewPortHandler, yAxis, trans); mLimitLinePaint.setTextAlign(Align.LEFT); @@ -145,15 +146,20 @@ protected void drawYLabels(Canvas c, float fixedPosition, float[] positions, flo for (int i = from; i < to; i++) { String text = mYAxis.getFormattedLabel(i); + CustomLabelDrawJob customLabelDrawJob = mYAxis.getCustomLabelDrawJob(); - c.drawText(text, positions[i * 2], fixedPosition - offset, mAxisLabelPaint); + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, text, positions[i * 2], fixedPosition - offset, mAxisLabelPaint); + } else { + c.drawText(text, positions[i * 2], fixedPosition - offset, mAxisLabelPaint); + } } } @Override protected float[] getTransformedPositions() { - if(mGetTransformedPositionsBuffer.length != mYAxis.mEntryCount * 2) { + if (mGetTransformedPositionsBuffer.length != mYAxis.mEntryCount * 2) { mGetTransformedPositionsBuffer = new float[mYAxis.mEntryCount * 2]; } float[] positions = mGetTransformedPositionsBuffer; @@ -213,6 +219,7 @@ protected void drawZeroLine(Canvas c) { protected Path mRenderLimitLinesPathBuffer = new Path(); protected float[] mRenderLimitLinesBuffer = new float[4]; + /** * Draws the LimitLines associated with this axis to the screen. * This is the standard XAxis renderer using the YAxis limit lines. @@ -283,24 +290,52 @@ public void renderLimitLines(Canvas c) { final LimitLine.LimitLabelPosition position = l.getLabelPosition(); + CustomLabelDrawJob customLabelDrawJob = l.getCustomLabelDrawJob(); + float x; + float y; + if (position == LimitLine.LimitLabelPosition.RIGHT_TOP) { final float labelLineHeight = Utils.calcTextHeight(mLimitLinePaint, label); mLimitLinePaint.setTextAlign(Align.LEFT); - c.drawText(label, pts[0] + xOffset, mViewPortHandler.contentTop() + yOffset + labelLineHeight, mLimitLinePaint); + x = pts[0] + xOffset; + y = mViewPortHandler.contentTop() + yOffset + labelLineHeight; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } else if (position == LimitLine.LimitLabelPosition.RIGHT_BOTTOM) { mLimitLinePaint.setTextAlign(Align.LEFT); - c.drawText(label, pts[0] + xOffset, mViewPortHandler.contentBottom() - yOffset, mLimitLinePaint); + x = pts[0] + xOffset; + y = mViewPortHandler.contentBottom() - yOffset; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } else if (position == LimitLine.LimitLabelPosition.LEFT_TOP) { - mLimitLinePaint.setTextAlign(Align.RIGHT); final float labelLineHeight = Utils.calcTextHeight(mLimitLinePaint, label); - c.drawText(label, pts[0] - xOffset, mViewPortHandler.contentTop() + yOffset + labelLineHeight, mLimitLinePaint); + mLimitLinePaint.setTextAlign(Align.RIGHT); + x = pts[0] - xOffset; + y = mViewPortHandler.contentTop() + yOffset + labelLineHeight; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } else { mLimitLinePaint.setTextAlign(Align.RIGHT); - c.drawText(label, pts[0] - xOffset, mViewPortHandler.contentBottom() - yOffset, mLimitLinePaint); + x = pts[0] - xOffset; + y = mViewPortHandler.contentBottom() - yOffset; + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, x, y, mLimitLinePaint); + } else { + c.drawText(label, x, y, mLimitLinePaint); + } } } diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRendererRadarChart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRendererRadarChart.java index ee7392e928..368cdc5095 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRendererRadarChart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/YAxisRendererRadarChart.java @@ -2,9 +2,9 @@ import android.graphics.Canvas; import android.graphics.Path; -import android.graphics.PointF; import com.github.mikephil.charting.charts.RadarChart; +import com.github.mikephil.charting.components.CustomLabelDrawJob; import com.github.mikephil.charting.components.LimitLine; import com.github.mikephil.charting.components.YAxis; import com.github.mikephil.charting.utils.MPPointF; @@ -66,7 +66,7 @@ protected void computeAxisValues(float min, float max) { float step = (float) range / (float) (labelCount - 1); mAxis.mEntryCount = labelCount; - if (mAxis.mEntries.length < labelCount) { + if (mAxis.mEntries.length != labelCount) { // Ensure stops contains at least numStops elements. mAxis.mEntries = new float[labelCount]; } @@ -103,7 +103,7 @@ protected void computeAxisValues(float min, float max) { mAxis.mEntryCount = n; - if (mAxis.mEntries.length < n) { + if (mAxis.mEntries.length != n) { // Ensure stops contains at least numStops elements. mAxis.mEntries = new float[n]; } @@ -126,7 +126,7 @@ protected void computeAxisValues(float min, float max) { if (centeringEnabled) { - if (mAxis.mCenteredEntries.length < n) { + if (mAxis.mCenteredEntries.length != n) { mAxis.mCenteredEntries = new float[n]; } @@ -168,8 +168,13 @@ public void renderAxisLabels(Canvas c) { Utils.getPosition(center, r, mChart.getRotationAngle(), pOut); String label = mYAxis.getFormattedLabel(j); + CustomLabelDrawJob customLabelDrawJob = mYAxis.getCustomLabelDrawJob(); - c.drawText(label, pOut.x + 10, pOut.y, mAxisLabelPaint); + if (customLabelDrawJob != null) { + customLabelDrawJob.drawLabel(c, label, pOut.x + 10, pOut.y, mAxisLabelPaint); + } else { + c.drawText(label, pOut.x + 10, pOut.y, mAxisLabelPaint); + } } MPPointF.recycleInstance(center); MPPointF.recycleInstance(pOut); diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/utils/Transformer.java b/MPChartLib/src/main/java/com/github/mikephil/charting/utils/Transformer.java index 0496bd0673..948c9f77c8 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/utils/Transformer.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/utils/Transformer.java @@ -98,7 +98,7 @@ public void prepareMatrixOffset(boolean inverted) { public float[] generateTransformedValuesScatter(IScatterDataSet data, float phaseX, float phaseY, int from, int to) { - final int count = (int) ((to - from) * phaseX + 1) * 2; + final int count = data.getEntryCount() < 1 ? 0 : (int) ((to - from) * phaseX + 1) * 2; if (valuePointsForGenerateTransformedValuesScatter.length != count) { valuePointsForGenerateTransformedValuesScatter = new float[count]; @@ -134,7 +134,7 @@ public float[] generateTransformedValuesScatter(IScatterDataSet data, float phas */ public float[] generateTransformedValuesBubble(IBubbleDataSet data, float phaseY, int from, int to) { - final int count = (to - from + 1) * 2; // (int) Math.ceil((to - from) * phaseX) * 2; + final int count = data.getEntryCount() < 1 ? 0 : (to - from + 1) * 2; // (int) Math.ceil((to - from) * phaseX) * 2; if (valuePointsForGenerateTransformedValuesBubble.length != count) { valuePointsForGenerateTransformedValuesBubble = new float[count]; @@ -172,7 +172,7 @@ public float[] generateTransformedValuesLine(ILineDataSet data, float phaseX, float phaseY, int min, int max) { - final int count = ((int) ((max - min) * phaseX) + 1) * 2; + final int count = data.getEntryCount() < 1 ? 0 : ((int) ((max - min) * phaseX) + 1) * 2; if (valuePointsForGenerateTransformedValuesLine.length != count) { valuePointsForGenerateTransformedValuesLine = new float[count]; @@ -209,7 +209,7 @@ public float[] generateTransformedValuesLine(ILineDataSet data, public float[] generateTransformedValuesCandle(ICandleDataSet data, float phaseX, float phaseY, int from, int to) { - final int count = (int) ((to - from) * phaseX + 1) * 2; + final int count = data.getEntryCount() < 1 ? 0 : (int) ((to - from) * phaseX + 1) * 2; if (valuePointsForGenerateTransformedValuesCandle.length != count) { valuePointsForGenerateTransformedValuesCandle = new float[count]; diff --git a/MPChartLib/src/test/java/com/github/mikephil/charting/test/LargeValueFormatterTest.java b/MPChartLib/src/test/java/com/github/mikephil/charting/test/LargeValueFormatterTest.java index f1e1e0279e..097954a7ac 100644 --- a/MPChartLib/src/test/java/com/github/mikephil/charting/test/LargeValueFormatterTest.java +++ b/MPChartLib/src/test/java/com/github/mikephil/charting/test/LargeValueFormatterTest.java @@ -16,80 +16,80 @@ public void test() { LargeValueFormatter formatter = new LargeValueFormatter(); - String result = formatter.getFormattedValue(5f, null); + String result = formatter.getFormattedValue(5f, null, 1, 0); assertEquals("5", result); - result = formatter.getFormattedValue(5.5f, null); + result = formatter.getFormattedValue(5.5f, null, 1, 0); assertEquals("5.5", result); - result = formatter.getFormattedValue(50f, null); + result = formatter.getFormattedValue(50f, null, 1, 0); assertEquals("50", result); - result = formatter.getFormattedValue(50.5f, null); + result = formatter.getFormattedValue(50.5f, null, 1, 0); assertEquals("50.5", result); - result = formatter.getFormattedValue(500f, null); + result = formatter.getFormattedValue(500f, null, 1, 0); assertEquals("500", result); - result = formatter.getFormattedValue(1100f, null); + result = formatter.getFormattedValue(1100f, null, 1, 0); assertEquals("1.1k", result); - result = formatter.getFormattedValue(10000f, null); + result = formatter.getFormattedValue(10000f, null, 1, 0); assertEquals("10k", result); - result = formatter.getFormattedValue(10500f, null); + result = formatter.getFormattedValue(10500f, null, 1, 0); assertEquals("10.5k", result); - result = formatter.getFormattedValue(100000f, null); + result = formatter.getFormattedValue(100000f, null, 1, 0); assertEquals("100k", result); - result = formatter.getFormattedValue(1000000f, null); + result = formatter.getFormattedValue(1000000f, null, 1, 0); assertEquals("1m", result); - result = formatter.getFormattedValue(1500000f, null); + result = formatter.getFormattedValue(1500000f, null, 1, 0); assertEquals("1.5m", result); - result = formatter.getFormattedValue(9500000f, null); + result = formatter.getFormattedValue(9500000f, null, 1, 0); assertEquals("9.5m", result); - result = formatter.getFormattedValue(22200000f, null); + result = formatter.getFormattedValue(22200000f, null, 1, 0); assertEquals("22.2m", result); - result = formatter.getFormattedValue(222000000f, null); + result = formatter.getFormattedValue(222000000f, null, 1, 0); assertEquals("222m", result); - result = formatter.getFormattedValue(1000000000f, null); + result = formatter.getFormattedValue(1000000000f, null, 1, 0); assertEquals("1b", result); - result = formatter.getFormattedValue(9900000000f, null); + result = formatter.getFormattedValue(9900000000f, null, 1, 0); assertEquals("9.9b", result); - result = formatter.getFormattedValue(99000000000f, null); + result = formatter.getFormattedValue(99000000000f, null, 1, 0); assertEquals("99b", result); - result = formatter.getFormattedValue(99500000000f, null); + result = formatter.getFormattedValue(99500000000f, null, 1, 0); assertEquals("99.5b", result); - result = formatter.getFormattedValue(999000000000f, null); + result = formatter.getFormattedValue(999000000000f, null, 1, 0); assertEquals("999b", result); - result = formatter.getFormattedValue(1000000000000f, null); + result = formatter.getFormattedValue(1000000000000f, null, 1, 0); assertEquals("1t", result); formatter.setSuffix(new String[]{"", "k", "m", "b", "t", "q"}); // quadrillion support - result = formatter.getFormattedValue(1000000000000000f, null); + result = formatter.getFormattedValue(1000000000000000f, null, 1, 0); assertEquals("1q", result); - result = formatter.getFormattedValue(1100000000000000f, null); + result = formatter.getFormattedValue(1100000000000000f, null, 1, 0); assertEquals("1.1q", result); - result = formatter.getFormattedValue(10000000000000000f, null); + result = formatter.getFormattedValue(10000000000000000f, null, 1, 0); assertEquals("10q", result); - result = formatter.getFormattedValue(13300000000000000f, null); + result = formatter.getFormattedValue(13300000000000000f, null, 1, 0); assertEquals("13.3q", result); - result = formatter.getFormattedValue(100000000000000000f, null); + result = formatter.getFormattedValue(100000000000000000f, null, 1, 0); assertEquals("100q", result); } } diff --git a/build.gradle b/build.gradle index 65ca5186cf..2b9506ee74 100644 --- a/build.gradle +++ b/build.gradle @@ -7,6 +7,7 @@ buildscript { classpath "io.realm:realm-gradle-plugin:4.2.0" classpath 'com.android.tools.build:gradle:3.1.2' classpath 'com.github.dcendents:android-maven-gradle-plugin:2.0' + classpath "org.jfrog.buildinfo:build-info-extractor-gradle:4.5.4" } }