From fc76f356a0692a877e587187febc1de3d01bf167 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Wed, 29 Nov 2023 14:03:48 +0100 Subject: [PATCH 1/2] Kotlin formatter --- .../formatter/DefaultAxisValueFormatter.java | 56 ---------- .../formatter/DefaultAxisValueFormatter.kt | 38 +++++++ .../formatter/DefaultFillFormatter.java | 46 -------- .../formatter/DefaultFillFormatter.kt | 28 +++++ .../formatter/DefaultValueFormatter.java | 71 ------------ .../formatter/DefaultValueFormatter.kt | 53 +++++++++ .../formatter/IndexAxisValueFormatter.java | 69 ------------ .../formatter/IndexAxisValueFormatter.kt | 35 ++++++ .../formatter/LargeValueFormatter.java | 103 ------------------ .../charting/formatter/LargeValueFormatter.kt | 83 ++++++++++++++ .../charting/formatter/PercentFormatter.java | 49 --------- .../charting/formatter/PercentFormatter.kt | 40 +++++++ .../formatter/StackedValueFormatter.java | 75 ------------- .../formatter/StackedValueFormatter.kt | 53 +++++++++ 14 files changed, 330 insertions(+), 469 deletions(-) delete mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultAxisValueFormatter.java create mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultAxisValueFormatter.kt delete mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultFillFormatter.java create mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultFillFormatter.kt delete mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultValueFormatter.java create mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultValueFormatter.kt delete mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IndexAxisValueFormatter.java create mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IndexAxisValueFormatter.kt delete mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/LargeValueFormatter.java create mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/LargeValueFormatter.kt delete mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/PercentFormatter.java create mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/PercentFormatter.kt delete mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/StackedValueFormatter.java create mode 100644 MPChartLib/src/main/java/com/github/mikephil/charting/formatter/StackedValueFormatter.kt 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 deleted file mode 100644 index 552c150e69..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultAxisValueFormatter.java +++ /dev/null @@ -1,56 +0,0 @@ -package com.github.mikephil.charting.formatter; - -import com.github.mikephil.charting.components.AxisBase; - -import java.text.DecimalFormat; - -/** - * Created by philipp on 02/06/16. - */ -public class DefaultAxisValueFormatter implements IAxisValueFormatter -{ - - /** - * decimalformat for formatting - */ - protected DecimalFormat mFormat; - - /** - * the number of decimal digits this formatter uses - */ - protected int digits = 0; - - /** - * Constructor that specifies to how many digits the value should be - * formatted. - * - * @param digits - */ - public DefaultAxisValueFormatter(int digits) { - this.digits = digits; - - StringBuffer b = new StringBuffer(); - for (int i = 0; i < digits; i++) { - if (i == 0) - b.append("."); - b.append("0"); - } - - mFormat = new DecimalFormat("###,###,###,##0" + b.toString()); - } - - @Override - public String getFormattedValue(float value, AxisBase axis) { - // avoid memory allocations here (for performance) - return mFormat.format(value); - } - - /** - * Returns the number of decimal digits this formatter uses or -1, if unspecified. - * - * @return - */ - public int getDecimalDigits() { - return digits; - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultAxisValueFormatter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultAxisValueFormatter.kt new file mode 100644 index 0000000000..9ad583e3fa --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultAxisValueFormatter.kt @@ -0,0 +1,38 @@ +package com.github.mikephil.charting.formatter + +import com.github.mikephil.charting.components.AxisBase +import java.text.DecimalFormat + +open class DefaultAxisValueFormatter(digits: Int) : IAxisValueFormatter { + /** + * decimal format for formatting + */ + protected var decimalFormat: DecimalFormat + /** + * Returns the number of decimal digits this formatter uses or -1, if unspecified. + */ + /** + * the number of decimal digits this formatter uses + */ + var decimalDigits = 0 + protected set + + /** + * Constructor that specifies to how many digits the value should be + * formatted. + */ + init { + decimalDigits = digits + val b = StringBuffer() + for (i in 0 until digits) { + if (i == 0) b.append(".") + b.append("0") + } + decimalFormat = DecimalFormat("###,###,###,##0$b") + } + + override fun getFormattedValue(value: Float, axis: AxisBase?): String? { + // avoid memory allocations here (for performance) + return decimalFormat.format(value.toDouble()) + } +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultFillFormatter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultFillFormatter.java deleted file mode 100644 index fc893584d6..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultFillFormatter.java +++ /dev/null @@ -1,46 +0,0 @@ -package com.github.mikephil.charting.formatter; - - -import com.github.mikephil.charting.data.LineData; -import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider; -import com.github.mikephil.charting.interfaces.datasets.ILineDataSet; - -import java.io.Serializable; - -/** - * Default formatter that calculates the position of the filled line. - * - * @author Philipp Jahoda - */ -public class DefaultFillFormatter implements IFillFormatter, Serializable { - - @Override - public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) { - - float fillMin = 0f; - float chartMaxY = dataProvider.getYChartMax(); - float chartMinY = dataProvider.getYChartMin(); - - LineData data = dataProvider.getLineData(); - - if (dataSet.getYMax() > 0 && dataSet.getYMin() < 0) { - fillMin = 0f; - } else { - - float max, min; - - if (data.getYMax() > 0) - max = 0f; - else - max = chartMaxY; - if (data.getYMin() < 0) - min = 0f; - else - min = chartMinY; - - fillMin = dataSet.getYMin() >= 0 ? min : max; - } - - return fillMin; - } -} \ No newline at end of file diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultFillFormatter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultFillFormatter.kt new file mode 100644 index 0000000000..5cee6d983b --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultFillFormatter.kt @@ -0,0 +1,28 @@ +package com.github.mikephil.charting.formatter + +import com.github.mikephil.charting.interfaces.dataprovider.LineDataProvider +import com.github.mikephil.charting.interfaces.datasets.ILineDataSet + +/** + * Default formatter that calculates the position of the filled line. + */ +open class DefaultFillFormatter : IFillFormatter { + + override fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider?): Float { + val fillMin: Float + val chartMaxY = dataProvider!!.yChartMax + val chartMinY = dataProvider.yChartMin + val data = dataProvider.lineData + fillMin = if (dataSet!!.yMax > 0 && dataSet.yMin < 0) { + 0f + } else { + val max: Float = if (data.yMax > 0) 0f else chartMaxY + val min: Float = if (data.yMin < 0) 0f else chartMinY + if (dataSet.yMin >= 0) + min + else + max + } + return fillMin + } +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultValueFormatter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultValueFormatter.java deleted file mode 100644 index e2fea4b079..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultValueFormatter.java +++ /dev/null @@ -1,71 +0,0 @@ - -package com.github.mikephil.charting.formatter; - -import com.github.mikephil.charting.data.Entry; -import com.github.mikephil.charting.utils.ViewPortHandler; - -import java.text.DecimalFormat; - -/** - * Default formatter used for formatting values inside the chart. Uses a DecimalFormat with - * pre-calculated number of digits (depending on max and min value). - * - * @author Philipp Jahoda - */ -public class DefaultValueFormatter implements IValueFormatter -{ - - /** - * DecimalFormat for formatting - */ - protected DecimalFormat mFormat; - - protected int mDecimalDigits; - - /** - * Constructor that specifies to how many digits the value should be - * formatted. - * - * @param digits - */ - public DefaultValueFormatter(int digits) { - setup(digits); - } - - /** - * Sets up the formatter with a given number of decimal digits. - * - * @param digits - */ - public void setup(int digits) { - - this.mDecimalDigits = digits; - - StringBuffer b = new StringBuffer(); - for (int i = 0; i < digits; i++) { - if (i == 0) - b.append("."); - b.append("0"); - } - - mFormat = new DecimalFormat("###,###,###,##0" + b.toString()); - } - - @Override - public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { - - // put more logic here ... - // avoid memory allocations here (for performance reasons) - - return mFormat.format(value); - } - - /** - * Returns the number of decimal digits this formatter uses. - * - * @return - */ - public int getDecimalDigits() { - return mDecimalDigits; - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultValueFormatter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultValueFormatter.kt new file mode 100644 index 0000000000..3d357a9817 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/DefaultValueFormatter.kt @@ -0,0 +1,53 @@ +package com.github.mikephil.charting.formatter + +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.utils.ViewPortHandler +import java.text.DecimalFormat + +/** + * Default formatter used for formatting values inside the chart. Uses a DecimalFormat with + * pre-calculated number of digits (depending on max and min value). + */ +open class DefaultValueFormatter(digits: Int) : IValueFormatter { + /** + * DecimalFormat for formatting + */ + protected var decimalFormat: DecimalFormat? = null + + /** + * Returns the number of decimal digits this formatter uses. + * + * @return + */ + var decimalDigits = 0 + protected set + + /** + * Constructor that specifies to how many digits the value should be formatted. + */ + init { + setup(digits) + } + + /** + * Sets up the formatter with a given number of decimal digits. + * + * @param digits + */ + fun setup(digits: Int) { + decimalDigits = digits + val b = StringBuffer() + for (i in 0 until digits) { + if (i == 0) b.append(".") + b.append("0") + } + decimalFormat = DecimalFormat("###,###,###,##0$b") + } + + override fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String? { + + // put more logic here ... + // avoid memory allocations here (for performance reasons) + return decimalFormat!!.format(value.toDouble()) + } +} \ No newline at end of file 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 deleted file mode 100644 index 07349a6a0e..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IndexAxisValueFormatter.java +++ /dev/null @@ -1,69 +0,0 @@ - -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; - -/** - * This formatter is used for passing an array of x-axis labels, on whole x steps. - */ -public class IndexAxisValueFormatter implements IAxisValueFormatter -{ - private String[] mValues = new String[] {}; - private int mValueCount = 0; - - /** - * An empty constructor. - * Use `setValues` to set the axis labels. - */ - public IndexAxisValueFormatter() { - } - - /** - * Constructor that specifies axis labels. - * - * @param values The values string array - */ - public IndexAxisValueFormatter(String[] values) { - if (values != null) - setValues(values); - } - - /** - * Constructor that specifies axis labels. - * - * @param values The values string array - */ - public IndexAxisValueFormatter(Collection values) { - if (values != null) - setValues(values.toArray(new String[values.size()])); - } - - public String getFormattedValue(float value, AxisBase axis) { - int index = Math.round(value); - - if (index < 0 || index >= mValueCount || index != (int)value) - return ""; - - return mValues[index]; - } - - public String[] getValues() - { - return mValues; - } - - public void setValues(String[] values) - { - if (values == null) - values = new String[] {}; - - this.mValues = values; - this.mValueCount = values.length; - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IndexAxisValueFormatter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IndexAxisValueFormatter.kt new file mode 100644 index 0000000000..d3a2e8dd87 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/IndexAxisValueFormatter.kt @@ -0,0 +1,35 @@ +package com.github.mikephil.charting.formatter + +import com.github.mikephil.charting.components.AxisBase +import kotlin.math.roundToInt + +/** + * This formatter is used for passing an array of x-axis labels, on whole x steps. + */ +open class IndexAxisValueFormatter : IAxisValueFormatter { + + /** + * Constructor that specifies axis labels. + * + * @param values The values string array + */ + constructor(values: Array?) { + if (values != null) this.values = values + } + + /** + * Constructor that specifies axis labels. + * + * @param values The values string array + */ + constructor(values: Collection?) { + if (values != null) this.values = values.toTypedArray() + } + + override fun getFormattedValue(value: Float, axis: AxisBase?): String { + val index = value.roundToInt() + return if (index < 0 || index >= values.size || index != value.toInt()) "" else values[index] + } + + var values: Array = arrayOf() +} 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 deleted file mode 100644 index 211401ad8a..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/LargeValueFormatter.java +++ /dev/null @@ -1,103 +0,0 @@ - -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; - -/** - * Predefined value-formatter that formats large numbers in a pretty way. - * Outputs: 856 = 856; 1000 = 1k; 5821 = 5.8k; 10500 = 10k; 101800 = 102k; - * 2000000 = 2m; 7800000 = 7.8m; 92150000 = 92m; 123200000 = 123m; 9999999 = - * 10m; 1000000000 = 1b; Special thanks to Roman Gromov - * (https://github.com/romangromov) for this piece of code. - * - * @author Philipp Jahoda - * @author Oleksandr Tyshkovets - */ -public class LargeValueFormatter implements IValueFormatter, IAxisValueFormatter -{ - - private String[] mSuffix = new String[]{ - "", "k", "m", "b", "t" - }; - private int mMaxLength = 5; - private DecimalFormat mFormat; - private String mText = ""; - - public LargeValueFormatter() { - mFormat = new DecimalFormat("###E00"); - } - - /** - * Creates a formatter that appends a specified text to the result string - * - * @param appendix a text that will be appended - */ - public LargeValueFormatter(String appendix) { - this(); - mText = appendix; - } - - // IValueFormatter - @Override - public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { - return makePretty(value) + mText; - } - - // IAxisValueFormatter - @Override - public String getFormattedValue(float value, AxisBase axis) { - return makePretty(value) + mText; - } - - /** - * Set an appendix text to be added at the end of the formatted value. - * - * @param appendix - */ - public void setAppendix(String appendix) { - this.mText = appendix; - } - - /** - * Set custom suffix to be appended after the values. - * Default suffix: ["", "k", "m", "b", "t"] - * - * @param suffix new suffix - */ - public void setSuffix(String[] suffix) { - this.mSuffix = suffix; - } - - public void setMaxLength(int maxLength) { - this.mMaxLength = maxLength; - } - - /** - * Formats each number properly. Special thanks to Roman Gromov - * (https://github.com/romangromov) for this piece of code. - */ - private String makePretty(double number) { - - String r = mFormat.format(number); - - int numericValue1 = Character.getNumericValue(r.charAt(r.length() - 1)); - int numericValue2 = Character.getNumericValue(r.charAt(r.length() - 2)); - int combined = Integer.valueOf(numericValue2 + "" + numericValue1); - - r = r.replaceAll("E[0-9][0-9]", mSuffix[combined / 3]); - - while (r.length() > mMaxLength || r.matches("[0-9]+\\.[a-z]")) { - r = r.substring(0, r.length() - 2) + r.substring(r.length() - 1); - } - - return r; - } - - public int getDecimalDigits() { - return 0; - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/LargeValueFormatter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/LargeValueFormatter.kt new file mode 100644 index 0000000000..7ae1fe3b19 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/LargeValueFormatter.kt @@ -0,0 +1,83 @@ +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 + +/** + * Predefined value-formatter that formats large numbers in a pretty way. + * Outputs: 856 = 856; 1000 = 1k; 5821 = 5.8k; 10500 = 10k; 101800 = 102k; + * 2000000 = 2m; 7800000 = 7.8m; 92150000 = 92m; 123200000 = 123m; 9999999 = + * 10m; 1000000000 = 1b; + * Special thanks to Roman Gromov + * (https://github.com/romangromov) for this piece of code. + */ +open class LargeValueFormatter() : IValueFormatter, IAxisValueFormatter { + + private var mSuffix = arrayOf( + "", "k", "m", "b", "t" + ) + private var mMaxLength = 5 + private val mFormat: DecimalFormat = DecimalFormat("###E00") + private var mText = "" + + /** + * Creates a formatter that appends a specified text to the result string + * + * @param appendix a text that will be appended + */ + constructor(appendix: String) : this() { + mText = appendix + } + + // IValueFormatter + override fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { + return makePretty(value.toDouble()) + mText + } + + // IAxisValueFormatter + override fun getFormattedValue(value: Float, axis: AxisBase?): String { + return makePretty(value.toDouble()) + mText + } + + /** + * Set an appendix text to be added at the end of the formatted value. + * + * @param appendix + */ + fun setAppendix(appendix: String) { + mText = appendix + } + + /** + * Set custom suffix to be appended after the values. + * Default suffix: ["", "k", "m", "b", "t"] + * + * @param suffix new suffix + */ + fun setSuffix(suffix: Array) { + mSuffix = suffix + } + + fun setMaxLength(maxLength: Int) { + mMaxLength = maxLength + } + + /** + * Formats each number properly. Special thanks to Roman Gromov + * (https://github.com/romangromov) for this piece of code. + */ + private fun makePretty(number: Double): String { + var r = mFormat.format(number) + val numericValue1 = Character.getNumericValue(r[r.length - 1]) + val numericValue2 = Character.getNumericValue(r[r.length - 2]) + val combined = Integer.valueOf(numericValue2.toString() + "" + numericValue1) + r = r.replace("E[0-9][0-9]".toRegex(), mSuffix[combined / 3]) + while (r.length > mMaxLength || r.matches("[0-9]+\\.[a-z]".toRegex())) { + r = r.substring(0, r.length - 2) + r.substring(r.length - 1) + } + return r + } + +} 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 deleted file mode 100644 index de8a10255a..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/PercentFormatter.java +++ /dev/null @@ -1,49 +0,0 @@ - -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; - -/** - * This IValueFormatter is just for convenience and simply puts a "%" sign after - * each value. (Recommeded for PieChart) - * - * @author Philipp Jahoda - */ -public class PercentFormatter implements IValueFormatter, IAxisValueFormatter -{ - - protected DecimalFormat mFormat; - - public PercentFormatter() { - mFormat = new DecimalFormat("###,###,##0.0"); - } - - /** - * Allow a custom decimalformat - * - * @param format - */ - public PercentFormatter(DecimalFormat format) { - this.mFormat = format; - } - - // IValueFormatter - @Override - public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { - return mFormat.format(value) + " %"; - } - - // IAxisValueFormatter - @Override - public String getFormattedValue(float value, AxisBase axis) { - return mFormat.format(value) + " %"; - } - - public int getDecimalDigits() { - return 1; - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/PercentFormatter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/PercentFormatter.kt new file mode 100644 index 0000000000..ca20515a9e --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/PercentFormatter.kt @@ -0,0 +1,40 @@ +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 + +/** + * This IValueFormatter is just for convenience and simply puts a "%" sign after + * each value. (Recommeded for PieChart) + */ +open class PercentFormatter : IValueFormatter, IAxisValueFormatter { + protected var decimalFormat: DecimalFormat + + constructor() { + decimalFormat = DecimalFormat("###,###,##0.0") + } + + /** + * Allow a custom decimal format + * + * @param format + */ + constructor(format: DecimalFormat) { + decimalFormat = format + } + + // IValueFormatter + override fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String? { + return decimalFormat.format(value.toDouble()) + " %" + } + + // IAxisValueFormatter + override fun getFormattedValue(value: Float, axis: AxisBase?): String? { + return decimalFormat.format(value.toDouble()) + " %" + } + + val decimalDigits: Int + get() = 1 +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/StackedValueFormatter.java b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/StackedValueFormatter.java deleted file mode 100644 index 0e8351634f..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/StackedValueFormatter.java +++ /dev/null @@ -1,75 +0,0 @@ -package com.github.mikephil.charting.formatter; - -import com.github.mikephil.charting.data.BarEntry; -import com.github.mikephil.charting.data.Entry; -import com.github.mikephil.charting.utils.ViewPortHandler; - -import java.text.DecimalFormat; - -/** - * Created by Philipp Jahoda on 28/01/16. - *

- * A formatter specifically for stacked BarChart that allows to specify whether the all stack values - * or just the top value should be drawn. - */ -public class StackedValueFormatter implements IValueFormatter -{ - - /** - * if true, all stack values of the stacked bar entry are drawn, else only top - */ - private boolean mDrawWholeStack; - - /** - * a string that should be appended behind the value - */ - private String mAppendix; - - private DecimalFormat mFormat; - - /** - * Constructor. - * - * @param drawWholeStack if true, all stack values of the stacked bar entry are drawn, else only top - * @param appendix a string that should be appended behind the value - * @param decimals the number of decimal digits to use - */ - public StackedValueFormatter(boolean drawWholeStack, String appendix, int decimals) { - this.mDrawWholeStack = drawWholeStack; - this.mAppendix = appendix; - - StringBuffer b = new StringBuffer(); - for (int i = 0; i < decimals; i++) { - if (i == 0) - b.append("."); - b.append("0"); - } - - this.mFormat = new DecimalFormat("###,###,###,##0" + b.toString()); - } - - @Override - public String getFormattedValue(float value, Entry entry, int dataSetIndex, ViewPortHandler viewPortHandler) { - - if (!mDrawWholeStack && entry instanceof BarEntry) { - - BarEntry barEntry = (BarEntry) entry; - float[] vals = barEntry.getYVals(); - - if (vals != null) { - - // find out if we are on top of the stack - if (vals[vals.length - 1] == value) { - - // return the "sum" across all stack values - return mFormat.format(barEntry.getY()) + mAppendix; - } else { - return ""; // return empty - } - } - } - - // return the "proposed" value - return mFormat.format(value) + mAppendix; - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/StackedValueFormatter.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/StackedValueFormatter.kt new file mode 100644 index 0000000000..e8dcdafaa0 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/formatter/StackedValueFormatter.kt @@ -0,0 +1,53 @@ +package com.github.mikephil.charting.formatter + +import com.github.mikephil.charting.data.BarEntry +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.utils.ViewPortHandler +import java.text.DecimalFormat + +/** + * A formatter specifically for stacked BarChart that allows to specify whether the all stack values + * or just the top value should be drawn. + */ +/** + * Constructor. + * + * @param drawWholeStack if true, all stack values of the stacked bar entry are drawn, else only top + * @param appendix a string that should be appended behind the value + * @param decimals the number of decimal digits to use + */ +open class StackedValueFormatter(private val drawWholeStack: Boolean, private val appendix: String, decimals: Int) : IValueFormatter { + private val mFormat: DecimalFormat + + init { + val b = StringBuffer() + for (i in 0 until decimals) { + if (i == 0) b.append(".") + b.append("0") + } + + this.mFormat = DecimalFormat("###,###,###,##0$b") + } + + override fun getFormattedValue(value: Float, entry: Entry?, dataSetIndex: Int, viewPortHandler: ViewPortHandler?): String { + if (!drawWholeStack && entry is BarEntry) { + val barEntry = entry + val vals = barEntry.yVals + + if (vals != null) { + // find out if we are on top of the stack + + return if (vals[vals.size - 1] == value) { + // return the "sum" across all stack values + + mFormat.format(barEntry.y.toDouble()) + appendix + } else { + "" // return empty + } + } + } + + // return the "proposed" value + return mFormat.format(value.toDouble()) + appendix + } +} From adbc37ed85ad6b8d7b4167ad63e5888f00d57394 Mon Sep 17 00:00:00 2001 From: Hannes Achleitner Date: Wed, 29 Nov 2023 14:24:13 +0100 Subject: [PATCH 2/2] Apply necessary changes --- .../mpchartexample/DataTools.kt | 124 ++++++++++-------- .../mpchartexample/LineChartActivity1.kt | 43 +++--- .../SpecificPositionsLineChartActivity.kt | 112 ++++++++-------- .../mikephil/charting/charts/Chart.java | 1 - 4 files changed, 141 insertions(+), 139 deletions(-) diff --git a/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/DataTools.kt b/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/DataTools.kt index 52dd87a808..3d3b4335d0 100644 --- a/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/DataTools.kt +++ b/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/DataTools.kt @@ -155,68 +155,78 @@ class DataTools { values.add(Entry(i.toFloat(), value, ContextCompat.getDrawable(context, R.drawable.star))) } } - val lineDataSet0: LineDataSet - if (lineChart.data != null && lineChart.data.dataSetCount > 0) { - lineDataSet0 = lineChart.data.getDataSetByIndex(0) as LineDataSet - lineDataSet0.entries = values - lineDataSet0.notifyDataSetChanged() - lineChart.data.notifyDataChanged() - lineChart.notifyDataSetChanged() - } else { - // create a dataset and give it a type - lineDataSet0 = LineDataSet(values, "DataSet 1") - lineDataSet0.setDrawIcons(false) - - // draw dashed line - lineDataSet0.enableDashedLine(10f, 5f, 0f) - - // black lines and points - lineDataSet0.color = Color.BLACK - lineDataSet0.setCircleColor(Color.BLACK) - - // line thickness and point size - lineDataSet0.lineWidth = 1f - lineDataSet0.circleRadius = 3f - - // draw points as solid circles - lineDataSet0.setDrawCircleHole(false) - - // customize legend entry - lineDataSet0.formLineWidth = 1f - lineDataSet0.formLineDashEffect = DashPathEffect(floatArrayOf(10f, 5f), 0f) - lineDataSet0.formSize = 15f - - // text size of values - lineDataSet0.valueTextSize = 9f - - // draw selection line as dashed - lineDataSet0.enableDashedHighlightLine(10f, 5f, 0f) + lineChart.data?.let { + if (it.dataSetCount > 0) { + val lineDataSet0 = it.getDataSetByIndex(0) as LineDataSet + lineDataSet0.entries = values + lineDataSet0.notifyDataSetChanged() + it.notifyDataChanged() + lineChart.notifyDataSetChanged() + } else + createDataset(values, lineChart, context) + } ?: run { + createDataset(values, lineChart, context) + } + } - // set the filled area - lineDataSet0.setDrawFilled(true) - lineDataSet0.fillFormatter = object : IFillFormatter { - override fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider?): Float { - return lineChart.axisLeft.axisMinimum - } + private fun createDataset( + values: ArrayList, + lineChart: LineChart, + context: Context + ) { + // create a dataset and give it a type + val lineDataSet01 = LineDataSet(values, "DataSet 1") + lineDataSet01.setDrawIcons(false) + + // draw dashed line + lineDataSet01.enableDashedLine(10f, 5f, 0f) + + // black lines and points + lineDataSet01.color = Color.BLACK + lineDataSet01.setCircleColor(Color.BLACK) + + // line thickness and point size + lineDataSet01.lineWidth = 1f + lineDataSet01.circleRadius = 3f + + // draw points as solid circles + lineDataSet01.setDrawCircleHole(false) + + // customize legend entry + lineDataSet01.formLineWidth = 1f + lineDataSet01.formLineDashEffect = DashPathEffect(floatArrayOf(10f, 5f), 0f) + lineDataSet01.formSize = 15f + + // text size of values + lineDataSet01.valueTextSize = 9f + + // draw selection line as dashed + lineDataSet01.enableDashedHighlightLine(10f, 5f, 0f) + + // set the filled area + lineDataSet01.setDrawFilled(true) + lineDataSet01.fillFormatter = object : IFillFormatter { + override fun getFillLinePosition(dataSet: ILineDataSet?, dataProvider: LineDataProvider?): Float { + return lineChart.axisLeft.axisMinimum } + } - // set color of filled area - if (Utils.getSDKInt() >= 18) { - // drawables only supported on api level 18 and above - val drawable = ContextCompat.getDrawable(context, R.drawable.fade_blue) - lineDataSet0.fillDrawable = drawable - } else { - lineDataSet0.fillColor = Color.BLACK - } - val dataSets = ArrayList() - dataSets.add(lineDataSet0) // add the data sets + // set color of filled area + if (Utils.getSDKInt() >= 18) { + // drawables only supported on api level 18 and above + val drawable = ContextCompat.getDrawable(context, R.drawable.fade_blue) + lineDataSet01.fillDrawable = drawable + } else { + lineDataSet01.fillColor = Color.BLACK + } + val dataSets = ArrayList() + dataSets.add(lineDataSet01) // add the data sets - // create a data object with the data sets - val data = LineData(dataSets) + // create a data object with the data sets + val data = LineData(dataSets) - // set data - lineChart.data = data - } + // set data + lineChart.data = data } } } diff --git a/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/LineChartActivity1.kt b/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/LineChartActivity1.kt index e49f62a0d4..4233e2bb64 100644 --- a/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/LineChartActivity1.kt +++ b/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/LineChartActivity1.kt @@ -139,70 +139,63 @@ class LineChartActivity1 : DemoBase(), OnSeekBarChangeListener, OnChartValueSele } R.id.actionToggleValues -> { - val sets = binding.chart1.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + binding.chart1.data?.dataSets?.forEach { + val set = it as LineDataSet set.setDrawValues(!set.isDrawValuesEnabled) } binding.chart1.invalidate() } R.id.actionToggleIcons -> { - val sets = binding.chart1.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + binding.chart1.data?.dataSets?.forEach { + val set = it as LineDataSet set.setDrawIcons(!set.isDrawIconsEnabled) + binding.chart1.invalidate() } - binding.chart1.invalidate() } R.id.actionToggleHighlight -> { - if (binding.chart1.data != null) { - binding.chart1.data.isHighlightEnabled = !binding.chart1.data.isHighlightEnabled + binding.chart1.data?.let { + it.isHighlightEnabled = !it.isHighlightEnabled binding.chart1.invalidate() } } R.id.actionToggleFilled -> { - val sets = binding.chart1.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + binding.chart1.data?.dataSets?.let { + val set = it as LineDataSet set.setDrawFilled(!set.isDrawFilledEnabled) + binding.chart1.invalidate() } - binding.chart1.invalidate() } R.id.actionToggleCircles -> { - val sets = binding.chart1.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + binding.chart1.data?.dataSets?.forEach { + val set = it as LineDataSet set.setDrawCircles(!set.isDrawCirclesEnabled) } binding.chart1.invalidate() } R.id.actionToggleCubic -> { - val sets = binding.chart1.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + binding.chart1.data?.dataSets?.forEach { + val set = it as LineDataSet set.mode = if (set.mode == LineDataSet.Mode.CUBIC_BEZIER) LineDataSet.Mode.LINEAR else LineDataSet.Mode.CUBIC_BEZIER } binding.chart1.invalidate() } R.id.actionToggleStepped -> { - val sets = binding.chart1.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + binding.chart1.data?.dataSets?.forEach { + val set = it as LineDataSet set.mode = if (set.mode == LineDataSet.Mode.STEPPED) LineDataSet.Mode.LINEAR else LineDataSet.Mode.STEPPED } binding.chart1.invalidate() } R.id.actionToggleHorizontalCubic -> { - val sets = binding.chart1.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + binding.chart1.data?.dataSets?.forEach { + val set = it as LineDataSet set.mode = if (set.mode == LineDataSet.Mode.HORIZONTAL_BEZIER) LineDataSet.Mode.LINEAR else LineDataSet.Mode.HORIZONTAL_BEZIER } binding.chart1.invalidate() diff --git a/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/SpecificPositionsLineChartActivity.kt b/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/SpecificPositionsLineChartActivity.kt index 7dac2d26da..ac96a956da 100644 --- a/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/SpecificPositionsLineChartActivity.kt +++ b/MPChartExample/src/main/java/com/xxmassdeveloper/mpchartexample/SpecificPositionsLineChartActivity.kt @@ -140,61 +140,55 @@ class SpecificPositionsLineChartActivity : DemoBase(), OnSeekBarChangeListener, override fun onOptionsItemSelected(item: MenuItem): Boolean { when (item.itemId) { R.id.actionToggleValues -> { - val sets = mChart!!.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + mChart!!.data?.dataSets?.forEach { + val set = it as LineDataSet set.setDrawValues(!set.isDrawValuesEnabled) } mChart!!.invalidate() } R.id.actionToggleHighlight -> { - if (mChart!!.data != null) { - mChart!!.data.isHighlightEnabled = !mChart!!.data.isHighlightEnabled + mChart!!.data?.let { + it.isHighlightEnabled = !it.isHighlightEnabled mChart!!.invalidate() } } R.id.actionToggleFilled -> { - val sets = mChart!!.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + mChart!!.data?.dataSets?.forEach { + val set = it as LineDataSet set.setDrawFilled(!set.isDrawFilledEnabled) } mChart!!.invalidate() } R.id.actionToggleCircles -> { - val sets = mChart!!.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + mChart!!.data?.dataSets?.forEach { + val set = it as LineDataSet set.setDrawCircles(!set.isDrawCirclesEnabled) } mChart!!.invalidate() } R.id.actionToggleCubic -> { - val sets = mChart!!.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + mChart!!.data?.dataSets?.forEach { + val set = it as LineDataSet set.mode = if (set.mode == LineDataSet.Mode.CUBIC_BEZIER) LineDataSet.Mode.LINEAR else LineDataSet.Mode.CUBIC_BEZIER } mChart!!.invalidate() } R.id.actionToggleStepped -> { - val sets = mChart!!.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + mChart!!.data?.dataSets?.forEach { + val set = it as LineDataSet set.mode = if (set.mode == LineDataSet.Mode.STEPPED) LineDataSet.Mode.LINEAR else LineDataSet.Mode.STEPPED } mChart!!.invalidate() } R.id.actionToggleHorizontalCubic -> { - val sets = mChart!!.data.dataSets - for (iSet in sets) { - val set = iSet as LineDataSet + mChart!!.data?.dataSets?.forEach { + val set = it as LineDataSet set.mode = if (set.mode == LineDataSet.Mode.HORIZONTAL_BEZIER) LineDataSet.Mode.LINEAR else LineDataSet.Mode.HORIZONTAL_BEZIER } mChart!!.invalidate() @@ -251,45 +245,51 @@ class SpecificPositionsLineChartActivity : DemoBase(), OnSeekBarChangeListener, val `val` = (sampleValues[i]!!.toFloat() * range) + 3 values.add(Entry(i.toFloat(), `val`)) } - val set1: LineDataSet - if (mChart!!.data != null && mChart!!.data.dataSetCount > 0) { - set1 = mChart!!.data.getDataSetByIndex(0) as LineDataSet - set1.entries = values - mChart!!.data.notifyDataChanged() - mChart!!.notifyDataSetChanged() + mChart!!.data?.let { + if (it.dataSetCount > 0) { + val set1 = it.getDataSetByIndex(0) as LineDataSet + set1.entries = values + it.notifyDataChanged() + mChart!!.notifyDataSetChanged() + } else + createDataset(values) + } ?: run { + createDataset(values) + } + } + + private fun createDataset(values: ArrayList) { + // create a dataset and give it a type + val set11 = LineDataSet(values, "DataSet 1") + + // set the line to be drawn like this "- - - - - -" + set11.enableDashedLine(10f, 5f, 0f) + set11.enableDashedHighlightLine(10f, 5f, 0f) + set11.color = Color.BLACK + set11.setCircleColor(Color.BLACK) + set11.lineWidth = 1f + set11.circleRadius = 3f + set11.setDrawCircleHole(false) + set11.valueTextSize = 9f + set11.setDrawFilled(true) + set11.formLineWidth = 1f + set11.formLineDashEffect = DashPathEffect(floatArrayOf(10f, 5f), 0f) + set11.formSize = 15f + if (Utils.getSDKInt() >= 18) { + // fill drawable only supported on api level 18 and above + val drawable = ContextCompat.getDrawable(this, R.drawable.fade_blue) + set11.fillDrawable = drawable } else { - // create a dataset and give it a type - set1 = LineDataSet(values, "DataSet 1") - - // set the line to be drawn like this "- - - - - -" - set1.enableDashedLine(10f, 5f, 0f) - set1.enableDashedHighlightLine(10f, 5f, 0f) - set1.color = Color.BLACK - set1.setCircleColor(Color.BLACK) - set1.lineWidth = 1f - set1.circleRadius = 3f - set1.setDrawCircleHole(false) - set1.valueTextSize = 9f - set1.setDrawFilled(true) - set1.formLineWidth = 1f - set1.formLineDashEffect = DashPathEffect(floatArrayOf(10f, 5f), 0f) - set1.formSize = 15f - if (Utils.getSDKInt() >= 18) { - // fill drawable only supported on api level 18 and above - val drawable = ContextCompat.getDrawable(this, R.drawable.fade_blue) - set1.fillDrawable = drawable - } else { - set1.fillColor = Color.BLACK - } - val dataSets = ArrayList() - dataSets.add(set1) // add the datasets + set11.fillColor = Color.BLACK + } + val dataSets = ArrayList() + dataSets.add(set11) // add the datasets - // create a data object with the datasets - val data = LineData(dataSets) + // create a data object with the datasets + val data = LineData(dataSets) - // set data - mChart!!.data = data - } + // set data + mChart!!.data = data } override fun onChartGestureStart(me: MotionEvent, lastPerformedGesture: ChartGesture) { diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/Chart.java b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/Chart.java index 50094913f9..97d8122083 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/charts/Chart.java +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/charts/Chart.java @@ -1313,7 +1313,6 @@ public void setDrawMarkers(boolean enabled) { /** * Returns the ChartData object that has been set for the chart. */ - @NonNull public T getData() { return mData; }