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 deleted file mode 100644 index 3b89562eb3..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/components/AxisBase.java +++ /dev/null @@ -1,846 +0,0 @@ - -package com.github.mikephil.charting.components; - -import android.graphics.Color; -import android.graphics.DashPathEffect; -import android.graphics.Paint; -import android.util.Log; - -import com.github.mikephil.charting.formatter.DefaultAxisValueFormatter; -import com.github.mikephil.charting.formatter.IAxisValueFormatter; -import com.github.mikephil.charting.utils.UtilsKtKt; - -import java.util.ArrayList; -import java.util.List; - -/** - * Base-class of all axes (previously called labels). - * - * @author Philipp Jahoda - */ -public abstract class AxisBase extends ComponentBase { - - /** - * custom formatter that is used instead of the auto-formatter if set - */ - protected IAxisValueFormatter mAxisValueFormatter; - - private int mGridColor = Color.GRAY; - - private float mGridLineWidth = 1f; - - private int mAxisLineColor = Color.GRAY; - - private float mAxisLineWidth = 1f; - - /** - * the actual array of entries - */ - public float[] mEntries = new float[]{}; - - /** - * axis label entries only used for centered labels - */ - public float[] mCenteredEntries = new float[]{}; - - /** - * the number of entries the legend contains - */ - public int mEntryCount; - - /** - * the number of decimal digits to use - */ - public int mDecimals; - - /** - * the number of label entries the axis should have, default 6 - */ - private int mLabelCount = 6; - - /** - * the minimum interval between axis values - */ - protected float mGranularity = 1.0f; - - /** - * When true, axis labels are controlled by the `granularity` property. - * When false, axis values could possibly be repeated. - * This could happen if two adjacent axis values are rounded to same value. - * If using granularity this could be avoided by having fewer axis values visible. - */ - protected boolean mGranularityEnabled = false; - - /** - * if true, the set number of y-labels will be forced - */ - protected boolean mForceLabels = false; - - /** - * flag indicating if the grid lines for this axis should be drawn - */ - protected boolean mDrawGridLines = true; - - /** - * flag that indicates if the line alongside the axis is drawn or not - */ - protected boolean mDrawAxisLine = true; - - /** - * flag that indicates of the labels of this axis should be drawn or not - */ - protected boolean mDrawLabels = true; - - protected boolean mCenterAxisLabels = false; - - /** - * the path effect of the axis line that makes dashed lines possible - */ - private DashPathEffect mAxisLineDashPathEffect = null; - - /** - * the path effect of the grid lines that makes dashed lines possible - */ - private DashPathEffect mGridDashPathEffect = null; - - /** - * array of limit lines that can be set for the axis - */ - protected List mLimitLines; - - /** - * array of limit ranges that can be set for the axis - */ - protected List mLimitRanges; - - /** - * flag indicating the limit lines layer depth - */ - protected boolean mDrawLimitLineBehindData = false; - - /** - * flag indicating the grid lines layer depth - */ - protected boolean mDrawGridLinesBehindData = true; - - /** - * Extra spacing for `axisMinimum` to be added to automatically calculated `axisMinimum` - */ - protected float mSpaceMin = 0.f; - - /** - * Extra spacing for `axisMaximum` to be added to automatically calculated `axisMaximum` - */ - protected float mSpaceMax = 0.f; - - /** - * flag indicating that the axis-min value has been customized - */ - protected boolean mCustomAxisMin = false; - - /** - * flag indicating that the axis-max value has been customized - */ - protected boolean mCustomAxisMax = false; - - /** - * don't touch this direclty, use setter - */ - public float mAxisMaximum = 0f; - - /** - * don't touch this directly, use setter - */ - public float mAxisMinimum = 0f; - - /** - * the total range of values this axis covers - */ - public float mAxisRange = 0f; - - private int mAxisMinLabels = 2; - private int mAxisMaxLabels = 25; - - /** - * The minumum number of labels on the axis - */ - public int getAxisMinLabels() { - return mAxisMinLabels; - } - - /** - * The minumum number of labels on the axis - */ - public void setAxisMinLabels(int labels) { - if (labels > 0) - mAxisMinLabels = labels; - } - - /** - * The maximum number of labels on the axis - */ - public int getAxisMaxLabels() { - return mAxisMaxLabels; - } - - /** - * The maximum number of labels on the axis - */ - public void setAxisMaxLabels(int labels) { - if (labels > 0) - mAxisMaxLabels = labels; - } - - /** - * if true, then labels and lines are displayed using specificPositions instead of computed ones - */ - private boolean showSpecificPositions = false; - - /** - * specify to which values labels and lines must be displayed. has no effect if not used showSpecificPositions set to true - */ - private float[] specificPositions = new float[]{}; - - /** - * default constructor - */ - public AxisBase() { - this.mTextSize = UtilsKtKt.convertDpToPixel(10f); - this.mXOffset = UtilsKtKt.convertDpToPixel(5f); - this.mYOffset = UtilsKtKt.convertDpToPixel(5f); - this.mLimitLines = new ArrayList<>(); - this.mLimitRanges = new ArrayList<>(); - } - - /** - * Set this to true to enable drawing the grid lines for this axis. - */ - public void setDrawGridLines(boolean enabled) { - mDrawGridLines = enabled; - } - - /** - * Returns true if drawing grid lines is enabled for this axis. - */ - public boolean isDrawGridLinesEnabled() { - return mDrawGridLines; - } - - /** - * Set this to true if the line alongside the axis should be drawn or not. - */ - public void setDrawAxisLine(boolean enabled) { - mDrawAxisLine = enabled; - } - - /** - * Returns true if the line alongside the axis should be drawn. - */ - public boolean isDrawAxisLineEnabled() { - return mDrawAxisLine; - } - - /** - * Centers the axis labels instead of drawing them at their original position. - * This is useful especially for grouped BarChart. - */ - public void setCenterAxisLabels(boolean enabled) { - mCenterAxisLabels = enabled; - } - - public boolean isCenterAxisLabelsEnabled() { - return mCenterAxisLabels && mEntryCount > 0; - } - - /** - * Sets the color of the grid lines for this axis (the horizontal lines - * coming from each label). - */ - public void setGridColor(int color) { - mGridColor = color; - } - - /** - * Returns the color of the grid lines for this axis (the horizontal lines - * coming from each label). - */ - public int getGridColor() { - return mGridColor; - } - - /** - * Sets the width of the border surrounding the chart in dp. - */ - public void setAxisLineWidth(float width) { - mAxisLineWidth = UtilsKtKt.convertDpToPixel(width); - } - - /** - * Returns the width of the axis line (line alongside the axis). - */ - public float getAxisLineWidth() { - return mAxisLineWidth; - } - - /** - * Sets the width of the grid lines that are drawn away from each axis - * label. - */ - public void setGridLineWidth(float width) { - mGridLineWidth = UtilsKtKt.convertDpToPixel(width); - } - - /** - * Returns the width of the grid lines that are drawn away from each axis - * label. - */ - public float getGridLineWidth() { - return mGridLineWidth; - } - - /** - * Sets the color of the border surrounding the chart. - */ - public void setAxisLineColor(int color) { - mAxisLineColor = color; - } - - /** - * Returns the color of the axis line (line alongside the axis). - */ - public int getAxisLineColor() { - return mAxisLineColor; - } - - /** - * Set this to true to enable drawing the labels of this axis (this will not - * affect drawing the grid lines or axis lines). - */ - public void setDrawLabels(boolean enabled) { - mDrawLabels = enabled; - } - - /** - * Returns true if drawing the labels is enabled for this axis. - */ - public boolean isDrawLabelsEnabled() { - return mDrawLabels; - } - - /** - * Sets the number of label entries for the y-axis max = 25, min = 2, default: 6, be aware - * that this number is not fixed. - * - * @param count the number of y-axis labels that should be displayed - */ - public void setLabelCount(int count) { - - if (count > getAxisMaxLabels()) - count = getAxisMaxLabels(); - if (count < getAxisMinLabels()) - count = getAxisMinLabels(); - - mLabelCount = count; - mForceLabels = false; - } - - /** - * sets the number of label entries for the y-axis max = 25, min = 2, default: 6, be aware - * that this number is not - * fixed (if force == false) and can only be approximated. - * - * @param count the number of y-axis labels that should be displayed - * @param force if enabled, the set label count will be forced, meaning that the exact - * specified count of labels will - * be drawn and evenly distributed alongside the axis - this might cause labels - * to have uneven values - */ - public void setLabelCount(int count, boolean force) { - - setLabelCount(count); - mForceLabels = force; - } - - /** - * Returns true if focing the y-label count is enabled. Default: false - */ - public boolean isForceLabelsEnabled() { - return mForceLabels; - } - - /** - * Returns the number of label entries the y-axis should have - */ - public int getLabelCount() { - return mLabelCount; - } - - /** - * @return true if granularity is enabled - */ - public boolean isGranularityEnabled() { - return mGranularityEnabled; - } - - /** - * Enabled/disable granularity control on axis value intervals. If enabled, the axis - * interval is not allowed to go below a certain granularity. Default: false - */ - public void setGranularityEnabled(boolean enabled) { - mGranularityEnabled = enabled; - } - - /** - * @return the minimum interval between axis values - */ - public float getGranularity() { - return mGranularity; - } - - /** - * Set a minimum interval for the axis when zooming in. The axis is not allowed to go below - * that limit. This can be used to avoid label duplicating when zooming in. - */ - public void setGranularity(float granularity) { - mGranularity = granularity; - // set this to true if it was disabled, as it makes no sense to call this method with granularity disabled - mGranularityEnabled = true; - } - - /** - * Adds a new LimitLine to this axis. - */ - public void addLimitLine(LimitLine l) { - mLimitLines.add(l); - - if (mLimitLines.size() > 6) { - Log.e("MPAndroiChart", - "Warning! You have more than 6 LimitLines on your axis, do you really want that?"); - } - } - - /** - * Adds a new LimitLine to this axis. - */ - public void addLimitRange(LimitRange l) { - mLimitRanges.add(l); - - if (mLimitRanges.size() > 6) { - Log.e("MPAndroiChart", - "Warning! You have more than 6 LimitLines on your axis, do you really want that?"); - } - } - - /** - * Removes the specified LimitLine from the axis. - */ - public void removeLimitLine(LimitLine l) { - mLimitLines.remove(l); - } - - /** - * Removes all LimitLines from the axis. - */ - public void removeAllLimitLines() { - mLimitLines.clear(); - } - - /** - * Removes the specified LimitRange from the axis. - */ - public void removeLimitRange(LimitRange l) { - mLimitRanges.remove(l); - } - - /** - * Removes all LimitLines from the axis. - */ - public void removeAllLimitRanges() { - mLimitRanges.clear(); - } - - /** - * Returns the LimitLines of this axis. - */ - public List getLimitLines() { - return mLimitLines; - } - - /** - * Returns the LimitRanges of this axis. - */ - public List getLimitRanges() { - return mLimitRanges; - } - - /** - * If this is set to true, the LimitLines are drawn behind the actual data, - * otherwise on top. Default: false - */ - public void setDrawLimitLinesBehindData(boolean enabled) { - mDrawLimitLineBehindData = enabled; - } - - public boolean isDrawLimitLinesBehindDataEnabled() { - return mDrawLimitLineBehindData; - } - - /** - * If this is set to false, the grid lines are draw on top of the actual data, - * otherwise behind. Default: true - */ - public void setDrawGridLinesBehindData(boolean enabled) { mDrawGridLinesBehindData = enabled; } - - public boolean isDrawGridLinesBehindDataEnabled() { - return mDrawGridLinesBehindData; - } - - /** - * Returns the longest formatted label (in terms of characters), this axis - * contains. - */ - public String getLongestLabel() { - - String longest = ""; - - for (int i = 0; i < mEntries.length; i++) { - String text = getFormattedLabel(i); - - if (text != null && longest.length() < text.length()) - longest = text; - } - - return longest; - } - - /** - * Returns the longest formatted label (in terms of px), this axis - * contains. - * If paint is null, then returns the longest formatted label (in terms of characters), this axis contains. - */ - public String getLongestLabel(Paint p) { - if (p == null) { - return getLongestLabel(); - } - String longest = ""; - float max = 0f; - - for (int i = 0; i < mEntries.length; i++) { - String text = getFormattedLabel(i); - if (text != null) { - float width = p.measureText(text); - if (max < width) { - longest = text; - } - } - } - - return longest; - } - - public String getFormattedLabel(int index) { - - if (index < 0 || index >= mEntries.length) - return ""; - else - return getValueFormatter().getFormattedValue(mEntries[index], this); - } - - /** - * Sets the formatter to be used for formatting the axis labels. If no formatter is set, the - * chart will - * automatically determine a reasonable formatting (concerning decimals) for all the values - * that are drawn inside - * the chart. Use chart.getDefaultValueFormatter() to use the formatter calculated by the chart. - */ - public void setValueFormatter(IAxisValueFormatter f) { - if (f == null) - mAxisValueFormatter = new DefaultAxisValueFormatter(mDecimals); - else - mAxisValueFormatter = f; - } - - /** - * Returns the formatter used for formatting the axis labels. - */ - public IAxisValueFormatter getValueFormatter() { - - if (mAxisValueFormatter == null || - (mAxisValueFormatter instanceof DefaultAxisValueFormatter && - ((DefaultAxisValueFormatter)mAxisValueFormatter).getDecimalDigits() != mDecimals)) - mAxisValueFormatter = new DefaultAxisValueFormatter(mDecimals); - - return mAxisValueFormatter; - } - - /** - * Enables the grid line to be drawn in dashed mode, e.g. like this - * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF. - * Keep in mind that hardware acceleration boosts performance. - * - * @param lineLength the length of the line pieces - * @param spaceLength the length of space in between the pieces - * @param phase offset, in degrees (normally, use 0) - */ - public void enableGridDashedLine(float lineLength, float spaceLength, float phase) { - mGridDashPathEffect = new DashPathEffect(new float[]{ - lineLength, spaceLength - }, phase); - } - - /** - * Enables the grid line to be drawn in dashed mode, e.g. like this - * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF. - * Keep in mind that hardware acceleration boosts performance. - * - * @param effect the DashPathEffect - */ - public void setGridDashedLine(DashPathEffect effect) { - mGridDashPathEffect = effect; - } - - /** - * Disables the grid line to be drawn in dashed mode. - */ - public void disableGridDashedLine() { - mGridDashPathEffect = null; - } - - /** - * Returns true if the grid dashed-line effect is enabled, false if not. - */ - public boolean isGridDashedLineEnabled() { - return mGridDashPathEffect != null; - } - - /** - * returns the DashPathEffect that is set for grid line - */ - public DashPathEffect getGridDashPathEffect() { - return mGridDashPathEffect; - } - - - /** - * Enables the axis line to be drawn in dashed mode, e.g. like this - * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF. - * Keep in mind that hardware acceleration boosts performance. - * - * @param lineLength the length of the line pieces - * @param spaceLength the length of space in between the pieces - * @param phase offset, in degrees (normally, use 0) - */ - public void enableAxisLineDashedLine(float lineLength, float spaceLength, float phase) { - mAxisLineDashPathEffect = new DashPathEffect(new float[]{ - lineLength, spaceLength - }, phase); - } - - /** - * Enables the axis line to be drawn in dashed mode, e.g. like this - * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF. - * Keep in mind that hardware acceleration boosts performance. - * - * @param effect the DashPathEffect - */ - public void setAxisLineDashedLine(DashPathEffect effect) { - mAxisLineDashPathEffect = effect; - } - - /** - * Disables the axis line to be drawn in dashed mode. - */ - public void disableAxisLineDashedLine() { - mAxisLineDashPathEffect = null; - } - - /** - * Returns true if the axis dashed-line effect is enabled, false if not. - */ - public boolean isAxisLineDashedLineEnabled() { - return mAxisLineDashPathEffect != null; - } - - /** - * returns the DashPathEffect that is set for axis line - */ - public DashPathEffect getAxisLineDashPathEffect() { - return mAxisLineDashPathEffect; - } - - /** - * ###### BELOW CODE RELATED TO CUSTOM AXIS VALUES ###### - */ - - public float getAxisMaximum() { - return mAxisMaximum; - } - - public float getAxisMinimum() { - return mAxisMinimum; - } - - /** - * By calling this method, any custom maximum value that has been previously set is reseted, - * and the calculation is - * done automatically. - */ - public void resetAxisMaximum() { - mCustomAxisMax = false; - } - - /** - * Returns true if the axis max value has been customized (and is not calculated automatically) - */ - public boolean isAxisMaxCustom() { - return mCustomAxisMax; - } - - /** - * By calling this method, any custom minimum value that has been previously set is reseted, - * and the calculation is - * done automatically. - */ - public void resetAxisMinimum() { - mCustomAxisMin = false; - } - - /** - * Returns true if the axis min value has been customized (and is not calculated automatically) - */ - public boolean isAxisMinCustom() { - return mCustomAxisMin; - } - - /** - * Set a custom minimum value for this axis. If set, this value will not be calculated - * automatically depending on - * the provided data. Use resetAxisMinValue() to undo this. Do not forget to call - * setStartAtZero(false) if you use - * this method. Otherwise, the axis-minimum value will still be forced to 0. - */ - public void setAxisMinimum(float min) { - mCustomAxisMin = true; - mAxisMinimum = min; - this.mAxisRange = Math.abs(mAxisMaximum - min); - } - - /** - * Use setAxisMinimum(...) instead. - */ - @Deprecated - public void setAxisMinValue(float min) { - setAxisMinimum(min); - } - - /** - * Set a custom maximum value for this axis. If set, this value will not be calculated - * automatically depending on - * the provided data. Use resetAxisMaxValue() to undo this. - */ - public void setAxisMaximum(float max) { - mCustomAxisMax = true; - mAxisMaximum = max; - this.mAxisRange = Math.abs(max - mAxisMinimum); - } - - /** - * Use setAxisMaximum(...) instead. - */ - @Deprecated - public void setAxisMaxValue(float max) { - setAxisMaximum(max); - } - - /** - * Calculates the minimum / maximum and range values of the axis with the given - * minimum and maximum values from the chart data. - * - * @param dataMin the min value according to chart data - * @param dataMax the max value according to chart data - */ - public void calculate(float dataMin, float dataMax) { - - // if custom, use value as is, else use data value - float min = mCustomAxisMin ? mAxisMinimum : (dataMin - mSpaceMin); - float max = mCustomAxisMax ? mAxisMaximum : (dataMax + mSpaceMax); - - // temporary range (before calculations) - float range = Math.abs(max - min); - - // in case all values are equal - if (range == 0f) { - max = max + 1f; - min = min - 1f; - } - - this.mAxisMinimum = min; - this.mAxisMaximum = max; - - // actual range - this.mAxisRange = Math.abs(max - min); - } - - /** - * Gets extra spacing for `axisMinimum` to be added to automatically calculated `axisMinimum` - */ - public float getSpaceMin() - { - return mSpaceMin; - } - - /** - * Sets extra spacing for `axisMinimum` to be added to automatically calculated `axisMinimum` - */ - public void setSpaceMin(float mSpaceMin) - { - this.mSpaceMin = mSpaceMin; - } - - /** - * Gets extra spacing for `axisMaximum` to be added to automatically calculated `axisMaximum` - */ - public float getSpaceMax() - { - return mSpaceMax; - } - - /** - * Sets extra spacing for `axisMaximum` to be added to automatically calculated `axisMaximum` - */ - public void setSpaceMax(float mSpaceMax) - { - this.mSpaceMax = mSpaceMax; - } - - /** - * if set to true, labels and lines will be displayed at the specific positions passed in via setSpecificPositions - */ - public void setShowSpecificPositions(boolean showSpecificPositions) - { - this.showSpecificPositions = showSpecificPositions; - } - - public boolean isShowSpecificPositions() - { - return showSpecificPositions; - } - - public void setSpecificPositions(float[] specificPositions) - { - this.specificPositions = specificPositions; - } - - public float[] getSpecificPositions() - { - return specificPositions; - } - - /** - * Sets the text color to use for the labels. Make sure to use - * getResources().getColor(...) when using a color from the resources. - */ - public void setTextColor(int color) { - super.setTextColor(color); - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/components/AxisBase.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/components/AxisBase.kt new file mode 100644 index 0000000000..475f423e12 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/components/AxisBase.kt @@ -0,0 +1,723 @@ +package com.github.mikephil.charting.components + +import android.graphics.Color +import android.graphics.DashPathEffect +import android.graphics.Paint +import android.util.Log +import com.github.mikephil.charting.formatter.DefaultAxisValueFormatter +import com.github.mikephil.charting.formatter.IAxisValueFormatter +import com.github.mikephil.charting.utils.convertDpToPixel +import kotlin.math.abs + +/** + * Base-class of all axes (previously called labels). + */ +abstract class AxisBase : ComponentBase() { + /** + * custom formatter that is used instead of the auto-formatter if set + */ + protected var mAxisValueFormatter: IAxisValueFormatter? = null + + /** + * Returns the color of the grid lines for this axis (the horizontal lines + * coming from each label). + */ + /** + * Sets the color of the grid lines for this axis (the horizontal lines + * coming from each label). + */ + var gridColor: Int = Color.GRAY + + private var mGridLineWidth = 1f + + /** + * Returns the color of the axis line (line alongside the axis). + */ + /** + * Sets the color of the border surrounding the chart. + */ + var axisLineColor: Int = Color.GRAY + + private var mAxisLineWidth = 1f + + /** + * the actual array of entries + */ + var mEntries: FloatArray = floatArrayOf() + + /** + * axis label entries only used for centered labels + */ + var mCenteredEntries: FloatArray = floatArrayOf() + + /** + * the number of entries the legend contains + */ + @JvmField + var mEntryCount: Int = 0 + + /** + * the number of decimal digits to use + */ + var mDecimals: Int = 0 + + /** + * the number of label entries the axis should have, default 6 + */ + private var mLabelCount = 6 + + /** + * the minimum interval between axis values + */ + protected var mGranularity: Float = 1.0f + + /** + * @return true if granularity is enabled + */ + /** + * Enabled/disable granularity control on axis value intervals. If enabled, the axis + * interval is not allowed to go below a certain granularity. Default: false + */ + /** + * When true, axis labels are controlled by the `granularity` property. + * When false, axis values could possibly be repeated. + * This could happen if two adjacent axis values are rounded to same value. + * If using granularity this could be avoided by having fewer axis values visible. + */ + var isGranularityEnabled: Boolean = false + + /** + * Returns true if focing the y-label count is enabled. Default: false + */ + /** + * if true, the set number of y-labels will be forced + */ + var isForceLabelsEnabled: Boolean = false + protected set + + /** + * Returns true if drawing grid lines is enabled for this axis. + */ + /** + * flag indicating if the grid lines for this axis should be drawn + */ + var isDrawGridLinesEnabled: Boolean = true + protected set + + /** + * Returns true if the line alongside the axis should be drawn. + */ + /** + * flag that indicates if the line alongside the axis is drawn or not + */ + var isDrawAxisLineEnabled: Boolean = true + protected set + + /** + * Returns true if drawing the labels is enabled for this axis. + */ + /** + * flag that indicates of the labels of this axis should be drawn or not + */ + var isDrawLabelsEnabled: Boolean = true + protected set + + protected var mCenterAxisLabels: Boolean = false + + /** + * returns the DashPathEffect that is set for axis line + */ + /** + * the path effect of the axis line that makes dashed lines possible + */ + var axisLineDashPathEffect: DashPathEffect? = null + private set + + /** + * returns the DashPathEffect that is set for grid line + */ + /** + * the path effect of the grid lines that makes dashed lines possible + */ + var gridDashPathEffect: DashPathEffect? = null + private set + + /** + * Returns the LimitLines of this axis. + */ + /** + * array of limit lines that can be set for the axis + */ + var limitLines: MutableList + protected set + + /** + * Returns the LimitRanges of this axis. + */ + /** + * array of limit ranges that can be set for the axis + */ + var limitRanges: MutableList + protected set + + /** + * flag indicating the limit lines layer depth + */ + var isDrawLimitLinesBehindDataEnabled: Boolean = false + protected set + + /** + * flag indicating the grid lines layer depth + */ + var isDrawGridLinesBehindDataEnabled: Boolean = true + protected set + + /** + * Gets extra spacing for `axisMinimum` to be added to automatically calculated `axisMinimum` + */ + /** + * Sets extra spacing for `axisMinimum` to be added to automatically calculated `axisMinimum` + */ + /** + * Extra spacing for `axisMinimum` to be added to automatically calculated `axisMinimum` + */ + var spaceMin: Float = 0f + + /** + * Gets extra spacing for `axisMaximum` to be added to automatically calculated `axisMaximum` + */ + /** + * Sets extra spacing for `axisMaximum` to be added to automatically calculated `axisMaximum` + */ + /** + * Extra spacing for `axisMaximum` to be added to automatically calculated `axisMaximum` + */ + var spaceMax: Float = 0f + + /** + * Returns true if the axis min value has been customized (and is not calculated automatically) + */ + /** + * flag indicating that the axis-min value has been customized + */ + var isAxisMinCustom: Boolean = false + protected set + + /** + * Returns true if the axis max value has been customized (and is not calculated automatically) + */ + /** + * flag indicating that the axis-max value has been customized + */ + var isAxisMaxCustom: Boolean = false + protected set + + /** + * don't touch this direclty, use setter + */ + @JvmField + var mAxisMaximum: Float = 0f + + /** + * don't touch this directly, use setter + */ + @JvmField + var mAxisMinimum: Float = 0f + + /** + * the total range of values this axis covers + */ + @JvmField + var mAxisRange: Float = 0f + + private var mAxisMinLabels = 2 + private var mAxisMaxLabels = 25 + + var axisMinLabels: Int + /** + * The minumum number of labels on the axis + */ + get() = mAxisMinLabels + /** + * The minumum number of labels on the axis + */ + set(labels) { + if (labels > 0) mAxisMinLabels = labels + } + + var axisMaxLabels: Int + /** + * The maximum number of labels on the axis + */ + get() = mAxisMaxLabels + /** + * The maximum number of labels on the axis + */ + set(labels) { + if (labels > 0) mAxisMaxLabels = labels + } + + /** + * if set to true, labels and lines will be displayed at the specific positions passed in via setSpecificPositions + */ + /** + * if true, then labels and lines are displayed using specificPositions instead of computed ones + */ + var isShowSpecificPositions: Boolean = false + + /** + * specify to which values labels and lines must be displayed. has no effect if not used showSpecificPositions set to true + */ + var specificPositions: FloatArray = floatArrayOf() + + /** + * default constructor + */ + init { + this.mTextSize = 10f.convertDpToPixel() + this.mXOffset = 5f.convertDpToPixel() + this.mYOffset = 5f.convertDpToPixel() + this.limitLines = ArrayList() + this.limitRanges = ArrayList() + } + + /** + * Set this to true to enable drawing the grid lines for this axis. + */ + fun setDrawGridLines(enabled: Boolean) { + this.isDrawGridLinesEnabled = enabled + } + + /** + * Set this to true if the line alongside the axis should be drawn or not. + */ + fun setDrawAxisLine(enabled: Boolean) { + this.isDrawAxisLineEnabled = enabled + } + + /** + * Centers the axis labels instead of drawing them at their original position. + * This is useful especially for grouped BarChart. + */ + fun setCenterAxisLabels(enabled: Boolean) { + mCenterAxisLabels = enabled + } + + val isCenterAxisLabelsEnabled: Boolean + get() = mCenterAxisLabels && mEntryCount > 0 + + var axisLineWidth: Float + /** + * Returns the width of the axis line (line alongside the axis). + */ + get() = mAxisLineWidth + /** + * Sets the width of the border surrounding the chart in dp. + */ + set(width) { + mAxisLineWidth = width.convertDpToPixel() + } + + var gridLineWidth: Float + /** + * Returns the width of the grid lines that are drawn away from each axis + * label. + */ + get() = mGridLineWidth + /** + * Sets the width of the grid lines that are drawn away from each axis + * label. + */ + set(width) { + mGridLineWidth = width.convertDpToPixel() + } + + /** + * Set this to true to enable drawing the labels of this axis (this will not + * affect drawing the grid lines or axis lines). + */ + fun setDrawLabels(enabled: Boolean) { + this.isDrawLabelsEnabled = enabled + } + + /** + * sets the number of label entries for the y-axis max = 25, min = 2, default: 6, be aware + * that this number is not + * fixed (if force == false) and can only be approximated. + * + * @param count the number of y-axis labels that should be displayed + * @param force if enabled, the set label count will be forced, meaning that the exact + * specified count of labels will + * be drawn and evenly distributed alongside the axis - this might cause labels + * to have uneven values + */ + fun setLabelCount(count: Int, force: Boolean) { + this.labelCount = count + this.isForceLabelsEnabled = force + } + + var labelCount: Int + /** + * Returns the number of label entries the y-axis should have + */ + get() = mLabelCount + /** + * Sets the number of label entries for the y-axis max = 25, min = 2, default: 6, be aware + * that this number is not fixed. + * + * @param count the number of y-axis labels that should be displayed + */ + set(count) { + var count = count + if (count > this.axisMaxLabels) count = this.axisMaxLabels + if (count < this.axisMinLabels) count = this.axisMinLabels + + mLabelCount = count + this.isForceLabelsEnabled = false + } + + var granularity: Float + /** + * @return the minimum interval between axis values + */ + get() = mGranularity + /** + * Set a minimum interval for the axis when zooming in. The axis is not allowed to go below + * that limit. This can be used to avoid label duplicating when zooming in. + */ + set(granularity) { + mGranularity = granularity + // set this to true if it was disabled, as it makes no sense to call this method with granularity disabled + this.isGranularityEnabled = true + } + + /** + * Adds a new LimitLine to this axis. + */ + fun addLimitLine(l: LimitLine) { + limitLines.add(l) + + if (limitLines.size > 6) { + Log.e( + "MPAndroiChart", + "Warning! You have more than 6 LimitLines on your axis, do you really want that?" + ) + } + } + + /** + * Adds a new LimitLine to this axis. + */ + fun addLimitRange(l: LimitRange) { + limitRanges.add(l) + + if (limitRanges.size > 6) { + Log.e( + "MPAndroiChart", + "Warning! You have more than 6 LimitLines on your axis, do you really want that?" + ) + } + } + + /** + * Removes the specified LimitLine from the axis. + */ + fun removeLimitLine(l: LimitLine) { + limitLines.remove(l) + } + + /** + * Removes all LimitLines from the axis. + */ + fun removeAllLimitLines() { + limitLines.clear() + } + + /** + * Removes the specified LimitRange from the axis. + */ + fun removeLimitRange(l: LimitRange) { + limitRanges.remove(l) + } + + /** + * Removes all LimitLines from the axis. + */ + fun removeAllLimitRanges() { + limitRanges.clear() + } + + /** + * If this is set to true, the LimitLines are drawn behind the actual data, + * otherwise on top. Default: false + */ + fun setDrawLimitLinesBehindData(enabled: Boolean) { + this.isDrawLimitLinesBehindDataEnabled = enabled + } + + /** + * If this is set to false, the grid lines are draw on top of the actual data, + * otherwise behind. Default: true + */ + fun setDrawGridLinesBehindData(enabled: Boolean) { + this.isDrawGridLinesBehindDataEnabled = enabled + } + + val longestLabel: String + /** + * Returns the longest formatted label (in terms of characters), this axis + * contains. + */ + get() { + var longest: String? = "" + + for (i in mEntries.indices) { + val text = getFormattedLabel(i) + + if (text != null && longest!!.length < text.length) longest = text + } + + return longest!! + } + + /** + * Returns the longest formatted label (in terms of px), this axis + * contains. + * If paint is null, then returns the longest formatted label (in terms of characters), this axis contains. + */ + fun getLongestLabel(p: Paint?): String { + if (p == null) { + return this.longestLabel + } + var longest: String? = "" + val max = 0f + + for (i in mEntries.indices) { + val text = getFormattedLabel(i) + if (text != null) { + val width = p.measureText(text) + if (max < width) { + longest = text + } + } + } + + return longest!! + } + + fun getFormattedLabel(index: Int): String? { + if (index < 0 || index >= mEntries.size) return "" + else return this.valueFormatter!!.getFormattedValue(mEntries[index], this) + } + + var valueFormatter: IAxisValueFormatter? + /** + * Returns the formatter used for formatting the axis labels. + */ + get() { + if (mAxisValueFormatter == null || + (mAxisValueFormatter is DefaultAxisValueFormatter && + (mAxisValueFormatter as DefaultAxisValueFormatter).decimalDigits != mDecimals) + ) mAxisValueFormatter = DefaultAxisValueFormatter(mDecimals) + + return mAxisValueFormatter + } + /** + * Sets the formatter to be used for formatting the axis labels. If no formatter is set, the + * chart will + * automatically determine a reasonable formatting (concerning decimals) for all the values + * that are drawn inside + * the chart. Use chart.getDefaultValueFormatter() to use the formatter calculated by the chart. + */ + set(f) { + if (f == null) mAxisValueFormatter = DefaultAxisValueFormatter(mDecimals) + else mAxisValueFormatter = f + } + + /** + * Enables the grid line to be drawn in dashed mode, e.g. like this + * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF. + * Keep in mind that hardware acceleration boosts performance. + * + * @param lineLength the length of the line pieces + * @param spaceLength the length of space in between the pieces + * @param phase offset, in degrees (normally, use 0) + */ + fun enableGridDashedLine(lineLength: Float, spaceLength: Float, phase: Float) { + this.gridDashPathEffect = DashPathEffect( + floatArrayOf( + lineLength, spaceLength + ), phase + ) + } + + /** + * Enables the grid line to be drawn in dashed mode, e.g. like this + * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF. + * Keep in mind that hardware acceleration boosts performance. + * + * @param effect the DashPathEffect + */ + fun setGridDashedLine(effect: DashPathEffect?) { + this.gridDashPathEffect = effect + } + + /** + * Disables the grid line to be drawn in dashed mode. + */ + fun disableGridDashedLine() { + this.gridDashPathEffect = null + } + + val isGridDashedLineEnabled: Boolean + /** + * Returns true if the grid dashed-line effect is enabled, false if not. + */ + get() = this.gridDashPathEffect != null + + + /** + * Enables the axis line to be drawn in dashed mode, e.g. like this + * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF. + * Keep in mind that hardware acceleration boosts performance. + * + * @param lineLength the length of the line pieces + * @param spaceLength the length of space in between the pieces + * @param phase offset, in degrees (normally, use 0) + */ + fun enableAxisLineDashedLine(lineLength: Float, spaceLength: Float, phase: Float) { + this.axisLineDashPathEffect = DashPathEffect( + floatArrayOf( + lineLength, spaceLength + ), phase + ) + } + + /** + * Enables the axis line to be drawn in dashed mode, e.g. like this + * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF. + * Keep in mind that hardware acceleration boosts performance. + * + * @param effect the DashPathEffect + */ + fun setAxisLineDashedLine(effect: DashPathEffect?) { + this.axisLineDashPathEffect = effect + } + + /** + * Disables the axis line to be drawn in dashed mode. + */ + fun disableAxisLineDashedLine() { + this.axisLineDashPathEffect = null + } + + val isAxisLineDashedLineEnabled: Boolean + /** + * Returns true if the axis dashed-line effect is enabled, false if not. + */ + get() = this.axisLineDashPathEffect != null + + var axisMaximum: Float + /** + * ###### BELOW CODE RELATED TO CUSTOM AXIS VALUES ###### + */ + get() = mAxisMaximum + /** + * Set a custom maximum value for this axis. If set, this value will not be calculated + * automatically depending on + * the provided data. Use resetAxisMaxValue() to undo this. + */ + set(max) { + this.isAxisMaxCustom = true + mAxisMaximum = max + this.mAxisRange = abs(max - mAxisMinimum) + } + + var axisMinimum: Float + get() = mAxisMinimum + /** + * Set a custom minimum value for this axis. If set, this value will not be calculated + * automatically depending on + * the provided data. Use resetAxisMinValue() to undo this. Do not forget to call + * setStartAtZero(false) if you use + * this method. Otherwise, the axis-minimum value will still be forced to 0. + */ + set(min) { + this.isAxisMinCustom = true + mAxisMinimum = min + this.mAxisRange = abs(mAxisMaximum - min) + } + + /** + * By calling this method, any custom maximum value that has been previously set is reseted, + * and the calculation is + * done automatically. + */ + fun resetAxisMaximum() { + this.isAxisMaxCustom = false + } + + /** + * By calling this method, any custom minimum value that has been previously set is reseted, + * and the calculation is + * done automatically. + */ + fun resetAxisMinimum() { + this.isAxisMinCustom = false + } + + /** + * Use setAxisMinimum(...) instead. + */ + @Deprecated("") + fun setAxisMinValue(min: Float) { + this.axisMinimum = min + } + + /** + * Use setAxisMaximum(...) instead. + */ + @Deprecated("") + fun setAxisMaxValue(max: Float) { + this.axisMaximum = max + } + + /** + * Calculates the minimum / maximum and range values of the axis with the given + * minimum and maximum values from the chart data. + * + * @param dataMin the min value according to chart data + * @param dataMax the max value according to chart data + */ + open fun calculate(dataMin: Float, dataMax: Float) { + // if custom, use value as is, else use data value + + var min = if (this.isAxisMinCustom) mAxisMinimum else (dataMin - this.spaceMin) + var max = if (this.isAxisMaxCustom) mAxisMaximum else (dataMax + this.spaceMax) + + // temporary range (before calculations) + val range = abs(max - min) + + // in case all values are equal + if (range == 0f) { + max = max + 1f + min = min - 1f + } + + this.mAxisMinimum = min + this.mAxisMaximum = max + + // actual range + this.mAxisRange = abs(max - min) + } + + /** + * Sets the text color to use for the labels. Make sure to use + * getResources().getColor(...) when using a color from the resources. + */ + override var textColor: Int + get() = super.textColor + set(value) { + super.textColor = value + } +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/components/MarkerView.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/components/MarkerView.kt index 213a6c182c..de01051a6e 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/components/MarkerView.kt +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/components/MarkerView.kt @@ -52,7 +52,7 @@ open class MarkerView(context: Context?, layoutResource: Int) : RelativeLayout(c var chartView: Chart<*>? get() = if (mWeakChart == null) null else mWeakChart!!.get() set(chart) { - mWeakChart = WeakReference?>(chart) + mWeakChart = WeakReference(chart) } override fun getOffsetForDrawingAtPoint(posX: Float, posY: Float): MPPointF { diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/components/XAxis.java b/MPChartLib/src/main/java/com/github/mikephil/charting/components/XAxis.java deleted file mode 100644 index 6ac1cba933..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/components/XAxis.java +++ /dev/null @@ -1,100 +0,0 @@ - -package com.github.mikephil.charting.components; - -import com.github.mikephil.charting.utils.UtilsKtKt; - -/** - * Class representing the x-axis labels settings. Only use the setter methods to - * modify it. Do not access public variables directly. Be aware that not all - * features the XLabels class provides are suitable for the RadarChart. - * - * @author Philipp Jahoda - */ -public class XAxis extends AxisBase { - - /** - * width of the x-axis labels in pixels - this is automatically - * calculated by the computeSize() methods in the renderers - */ - public int mLabelWidth = 1; - - /** - * height of the x-axis labels in pixels - this is automatically - * calculated by the computeSize() methods in the renderers - */ - public int mLabelHeight = 1; - - /** - * This is the angle for drawing the X axis labels (in degrees) - */ - protected float mLabelRotationAngle = 0f; - - /** - * if set to true, the chart will avoid that the first and last label entry - * in the chart "clip" off the edge of the chart - */ - private boolean mAvoidFirstLastClipping = false; - - /** - * the position of the x-labels relative to the chart - */ - private XAxisPosition mPosition = XAxisPosition.TOP; - - /** - * enum for the position of the x-labels relative to the chart - */ - public enum XAxisPosition { - TOP, BOTTOM, BOTH_SIDED, TOP_INSIDE, BOTTOM_INSIDE - } - - public XAxis() { - super(); - - mYOffset = UtilsKtKt.convertDpToPixel(4.f); // -3 - } - - /** - * returns the position of the x-labels - */ - public XAxisPosition getPosition() { - return mPosition; - } - - /** - * sets the position of the x-labels - */ - public void setPosition(XAxisPosition pos) { - mPosition = pos; - } - - /** - * returns the angle for drawing the X axis labels (in degrees) - */ - public float getLabelRotationAngle() { - return mLabelRotationAngle; - } - - /** - * sets the angle for drawing the X axis labels (in degrees) - * - * @param angle the angle in degrees - */ - public void setLabelRotationAngle(float angle) { - mLabelRotationAngle = angle; - } - - /** - * if set to true, the chart will avoid that the first and last label entry - * in the chart "clip" off the edge of the chart or the screen - */ - public void setAvoidFirstLastClipping(boolean enabled) { - mAvoidFirstLastClipping = enabled; - } - - /** - * returns true if avoid-first-last clipping is enabled, false if not - */ - public boolean isAvoidFirstLastClippingEnabled() { - return mAvoidFirstLastClipping; - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/components/XAxis.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/components/XAxis.kt new file mode 100644 index 0000000000..e2b75b9890 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/components/XAxis.kt @@ -0,0 +1,61 @@ +package com.github.mikephil.charting.components + +import com.github.mikephil.charting.utils.convertDpToPixel + +/** + * Class representing the x-axis labels settings. Only use the setter methods to + * modify it. Do not access public variables directly. Be aware that not all + * features the XLabels class provides are suitable for the RadarChart. + */ +class XAxis : AxisBase() { + /** + * width of the x-axis labels in pixels - this is automatically + * calculated by the computeSize() methods in the renderers + */ + @JvmField + var mLabelWidth: Int = 1 + + /** + * height of the x-axis labels in pixels - this is automatically + * calculated by the computeSize() methods in the renderers + */ + @JvmField + var mLabelHeight: Int = 1 + + /** + * This is the angle for drawing the X axis labels (in degrees) + */ + var labelRotationAngle: Float = 0f + + + /** + * if set to true, the chart will avoid that the first and last label entry + * in the chart "clip" off the edge of the chart + */ + var isAvoidFirstLastClippingEnabled: Boolean = false + private set + + /** + * the position of the x-labels relative to the chart + */ + var position: XAxisPosition? = XAxisPosition.TOP + + /** + * enum for the position of the x-labels relative to the chart + */ + enum class XAxisPosition { + TOP, BOTTOM, BOTH_SIDED, TOP_INSIDE, BOTTOM_INSIDE + } + + init { + mYOffset = 4f.convertDpToPixel() // -3 + } + + /** + * if set to true, the chart will avoid that the first and last label entry + * in the chart "clip" off the edge of the chart or the screen + */ + fun setAvoidFirstLastClipping(enabled: Boolean) { + this.isAvoidFirstLastClippingEnabled = enabled + } +} 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 deleted file mode 100644 index d8a04ea860..0000000000 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/components/YAxis.java +++ /dev/null @@ -1,426 +0,0 @@ -package com.github.mikephil.charting.components; - -import android.graphics.Color; -import android.graphics.Paint; - -import com.github.mikephil.charting.utils.Utils; -import com.github.mikephil.charting.utils.UtilsKtKt; - -/** - * Class representing the y-axis labels settings and its entries. Only use the setter methods to - * modify it. Do not - * access public variables directly. Be aware that not all features the YLabels class provides - * are suitable for the - * RadarChart. Customizations that affect the value range of the axis need to be applied before - * setting data for the - * chart. - * - * @author Philipp Jahoda - */ -public class YAxis extends AxisBase { - - /** - * indicates if the bottom y-label entry is drawn or not - */ - private final boolean mDrawBottomYLabelEntry = true; - - /** - * indicates if the top y-label entry is drawn or not - */ - private boolean mDrawTopYLabelEntry = true; - - /** - * flag that indicates if the axis is inverted or not - */ - protected boolean mInverted = false; - - /** - * flag that indicates if the zero-line should be drawn regardless of other grid lines - */ - protected boolean mDrawZeroLine = false; - - /** - * flag indicating that auto scale min restriction should be used - */ - private boolean mUseAutoScaleRestrictionMin = false; - - /** - * flag indicating that auto scale max restriction should be used - */ - private boolean mUseAutoScaleRestrictionMax = false; - - /** - * Color of the zero line - */ - protected int mZeroLineColor = Color.GRAY; - - /** - * Width of the zero line in pixels - */ - protected float mZeroLineWidth = 1f; - - /** - * axis space from the largest value to the top in percent of the total axis range - */ - protected float mSpacePercentTop = 10f; - - /** - * axis space from the smallest value to the bottom in percent of the total axis range - */ - protected float mSpacePercentBottom = 10f; - - /** - * the position of the y-labels relative to the chart - */ - private YAxisLabelPosition mPosition = YAxisLabelPosition.OUTSIDE_CHART; - - /** - * the horizontal offset of the y-label - */ - private float mXLabelOffset = 0.0f; - - /** - * enum for the position of the y-labels relative to the chart - */ - public enum YAxisLabelPosition { - OUTSIDE_CHART, INSIDE_CHART - } - - /** - * the side this axis object represents - */ - private final AxisDependency mAxisDependency; - - /** - * the minimum width that the axis should take (in dp). - *

- * default: 0.0 - */ - protected float mMinWidth = 0.f; - - /** - * the maximum width that the axis can take (in dp). - * use Inifinity for disabling the maximum - * default: Float.POSITIVE_INFINITY (no maximum specified) - */ - protected float mMaxWidth = Float.POSITIVE_INFINITY; - - /** - * Enum that specifies the axis a DataSet should be plotted against, either LEFT or RIGHT. - * - * @author Philipp Jahoda - */ - public enum AxisDependency { - LEFT, RIGHT - } - - public YAxis() { - super(); - - // default left - this.mAxisDependency = AxisDependency.LEFT; - this.mYOffset = 0f; - } - - public YAxis(AxisDependency position) { - super(); - this.mAxisDependency = position; - this.mYOffset = 0f; - } - - public AxisDependency getAxisDependency() { - return mAxisDependency; - } - - /** - * @return the minimum width that the axis should take (in dp). - */ - public float getMinWidth() { - return mMinWidth; - } - - /** - * Sets the minimum width that the axis should take (in dp). - */ - public void setMinWidth(float minWidth) { - mMinWidth = minWidth; - } - - /** - * @return the maximum width that the axis can take (in dp). - */ - public float getMaxWidth() { - return mMaxWidth; - } - - /** - * Sets the maximum width that the axis can take (in dp). - */ - public void setMaxWidth(float maxWidth) { - mMaxWidth = maxWidth; - } - - /** - * returns the position of the y-labels - */ - public YAxisLabelPosition getLabelPosition() { - return mPosition; - } - - /** - * sets the position of the y-labels - */ - public void setPosition(YAxisLabelPosition pos) { - mPosition = pos; - } - - /** - * returns the horizontal offset of the y-label - */ - public float getLabelXOffset() { - return mXLabelOffset; - } - - /** - * sets the horizontal offset of the y-label - */ - public void setLabelXOffset(float xOffset) { - mXLabelOffset = xOffset; - } - - /** - * returns true if drawing the top y-axis label entry is enabled - */ - public boolean isDrawTopYLabelEntryEnabled() { - return mDrawTopYLabelEntry; - } - - /** - * returns true if drawing the bottom y-axis label entry is enabled - */ - public boolean isDrawBottomYLabelEntryEnabled() { - return mDrawBottomYLabelEntry; - } - - /** - * set this to true to enable drawing the top y-label entry. Disabling this can be helpful - * when the top y-label and - * left x-label interfere with each other. default: true - */ - public void setDrawTopYLabelEntry(boolean enabled) { - mDrawTopYLabelEntry = enabled; - } - - /** - * If this is set to true, the y-axis is inverted which means that low values are on top of - * the chart, high values - * on bottom. - */ - public void setInverted(boolean enabled) { - mInverted = enabled; - } - - /** - * If this returns true, the y-axis is inverted. - */ - public boolean isInverted() { - return mInverted; - } - - /** - * This method is deprecated. - * Use setAxisMinimum(...) / setAxisMaximum(...) instead. - */ - @Deprecated - public void setStartAtZero(boolean startAtZero) { - if (startAtZero) - setAxisMinimum(0f); - else - resetAxisMinimum(); - } - - /** - * Sets the top axis space in percent of the full range. Default 10f - */ - public void setSpaceTop(float percent) { - mSpacePercentTop = percent; - } - - /** - * Returns the top axis space in percent of the full range. Default 10f - */ - public float getSpaceTop() { - return mSpacePercentTop; - } - - /** - * Sets the bottom axis space in percent of the full range. Default 10f - */ - public void setSpaceBottom(float percent) { - mSpacePercentBottom = percent; - } - - /** - * Returns the bottom axis space in percent of the full range. Default 10f - */ - public float getSpaceBottom() { - return mSpacePercentBottom; - } - - public boolean isDrawZeroLineEnabled() { - return mDrawZeroLine; - } - - /** - * Set this to true to draw the zero-line regardless of weather other - * grid-lines are enabled or not. Default: false - */ - public void setDrawZeroLine(boolean mDrawZeroLine) { - this.mDrawZeroLine = mDrawZeroLine; - } - - public int getZeroLineColor() { - return mZeroLineColor; - } - - /** - * Sets the color of the zero line - */ - public void setZeroLineColor(int color) { - mZeroLineColor = color; - } - - public float getZeroLineWidth() { - return mZeroLineWidth; - } - - /** - * Sets the width of the zero line in dp - */ - public void setZeroLineWidth(float width) { - this.mZeroLineWidth = UtilsKtKt.convertDpToPixel(width); - } - - /** - * This is for normal (not horizontal) charts horizontal spacing. - */ - public float getRequiredWidthSpace(Paint p) { - - p.setTextSize(mTextSize); - - String label = getLongestLabel(p); - float width = (float) Utils.calcTextWidth(p, label) + getXOffset() * 2f; - - float minWidth = getMinWidth(); - float maxWidth = getMaxWidth(); - - if (minWidth > 0.f) - minWidth = UtilsKtKt.convertDpToPixel(minWidth); - - if (maxWidth > 0.f && maxWidth != Float.POSITIVE_INFINITY) - maxWidth = UtilsKtKt.convertDpToPixel(maxWidth); - - width = Math.max(minWidth, Math.min(width, maxWidth > 0.0 ? maxWidth : width)); - - return width; - } - - /** - * This is for HorizontalBarChart vertical spacing. - */ - public float getRequiredHeightSpace(Paint p) { - - p.setTextSize(mTextSize); - - String label = getLongestLabel(p); - return (float) Utils.calcTextHeight(p, label) + getYOffset() * 2f; - } - - /** - * Returns true if this axis needs horizontal offset, false if no offset is needed. - */ - public boolean needsOffset() { - if (isEnabled() && isDrawLabelsEnabled() && getLabelPosition() == YAxisLabelPosition - .OUTSIDE_CHART) - return true; - else - return false; - } - - /** - * Returns true if autoscale restriction for axis min value is enabled - */ - @Deprecated - public boolean isUseAutoScaleMinRestriction( ) { - return mUseAutoScaleRestrictionMin; - } - - /** - * Sets autoscale restriction for axis min value as enabled/disabled - */ - @Deprecated - public void setUseAutoScaleMinRestriction( boolean isEnabled ) { - mUseAutoScaleRestrictionMin = isEnabled; - } - - /** - * Returns true if autoscale restriction for axis max value is enabled - */ - @Deprecated - public boolean isUseAutoScaleMaxRestriction() { - return mUseAutoScaleRestrictionMax; - } - - /** - * Sets autoscale restriction for axis max value as enabled/disabled - */ - @Deprecated - public void setUseAutoScaleMaxRestriction( boolean isEnabled ) { - mUseAutoScaleRestrictionMax = isEnabled; - } - - - @Override - public void calculate(float dataMin, float dataMax) { - - float min = dataMin; - float max = dataMax; - - // Make sure max is greater than min - // Discussion: https://github.com/danielgindi/Charts/pull/3650#discussion_r221409991 - if (min > max) - { - if (isAxisMaxCustom() && isAxisMinCustom()) - { - float t = min; - min = max; - max = t; - } - else if (isAxisMaxCustom()) - { - min = max < 0f ? max * 1.5f : max * 0.5f; - } - else if (isAxisMinCustom()) - { - max = min < 0f ? min * 0.5f : min * 1.5f; - } - } - - float range = Math.abs(max - min); - - // in case all values are equal - if (range == 0f) { - max = max + 1f; - min = min - 1f; - } - - // recalculate - range = Math.abs(max - min); - - // calc extra spacing - this.mAxisMinimum = isAxisMinCustom() ? this.mAxisMinimum : min - (range / 100f) * getSpaceBottom(); - this.mAxisMaximum = isAxisMaxCustom() ? this.mAxisMaximum : max + (range / 100f) * getSpaceTop(); - - this.mAxisRange = Math.abs(this.mAxisMinimum - this.mAxisMaximum); - } -} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/components/YAxis.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/components/YAxis.kt new file mode 100644 index 0000000000..f470c43a42 --- /dev/null +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/components/YAxis.kt @@ -0,0 +1,312 @@ +package com.github.mikephil.charting.components + +import android.graphics.Color +import android.graphics.Paint +import com.github.mikephil.charting.utils.Utils +import com.github.mikephil.charting.utils.convertDpToPixel +import kotlin.math.abs +import kotlin.math.max +import kotlin.math.min + +/** + * Class representing the y-axis labels settings and its entries. Only use the setter methods to + * modify it. Do not access public variables directly. Be aware that not all features the YLabels class provides + * are suitable for the RadarChart. Customizations that affect the value range of the axis need to be applied before + * setting data for the chart. + */ +class YAxis : AxisBase { + /** + * returns true if drawing the bottom y-axis label entry is enabled + */ + /** + * indicates if the bottom y-label entry is drawn or not + */ + val isDrawBottomYLabelEntryEnabled: Boolean = true + + /** + * returns true if drawing the top y-axis label entry is enabled + */ + /** + * indicates if the top y-label entry is drawn or not + */ + var isDrawTopYLabelEntryEnabled: Boolean = true + private set + + /** + * If this returns true, the y-axis is inverted. + */ + /** + * If this is set to true, the y-axis is inverted which means that low values are on top of + * the chart, high values + * on bottom. + */ + /** + * flag that indicates if the axis is inverted or not + */ + var isInverted: Boolean = false + + /** + * flag that indicates if the zero-line should be drawn regardless of other grid lines + */ + var isDrawZeroLineEnabled: Boolean = false + protected set + + /** + * Returns true if autoscale restriction for axis min value is enabled + */ + /** + * Sets autoscale restriction for axis min value as enabled/disabled + */ + /** + * flag indicating that auto scale min restriction should be used + */ + @get:Deprecated("") + @set:Deprecated("") + var isUseAutoScaleMinRestriction: Boolean = false + + /** + * Returns true if autoscale restriction for axis max value is enabled + */ + /** + * Sets autoscale restriction for axis max value as enabled/disabled + */ + /** + * flag indicating that auto scale max restriction should be used + */ + @get:Deprecated("") + @set:Deprecated("") + var isUseAutoScaleMaxRestriction: Boolean = false + + /** + * Sets the color of the zero line + */ + /** + * Color of the zero line + */ + var zeroLineColor: Int = Color.GRAY + + /** + * Width of the zero line in pixels + */ + protected var mZeroLineWidth: Float = 1f + + /** + * Returns the top axis space in percent of the full range. Default 10f + */ + /** + * Sets the top axis space in percent of the full range. Default 10f + */ + /** + * axis space from the largest value to the top in percent of the total axis range + */ + var spaceTop: Float = 10f + + /** + * Returns the bottom axis space in percent of the full range. Default 10f + */ + /** + * Sets the bottom axis space in percent of the full range. Default 10f + */ + /** + * axis space from the smallest value to the bottom in percent of the total axis range + */ + var spaceBottom: Float = 10f + + /** + * returns the position of the y-labels + */ + /** + * the position of the y-labels relative to the chart + */ + var labelPosition: YAxisLabelPosition? = YAxisLabelPosition.OUTSIDE_CHART + private set + + /** + * returns the horizontal offset of the y-label + */ + /** + * sets the horizontal offset of the y-label + */ + /** + * the horizontal offset of the y-label + */ + var labelXOffset: Float = 0.0f + + /** + * enum for the position of the y-labels relative to the chart + */ + enum class YAxisLabelPosition { + OUTSIDE_CHART, INSIDE_CHART + } + + /** + * the side this axis object represents + */ + val axisDependency: AxisDependency? + + /** + * @return the minimum width that the axis should take (in dp). + */ + /** + * Sets the minimum width that the axis should take (in dp). + */ + /** + * the minimum width that the axis should take (in dp). + * + * + * default: 0.0 + */ + var minWidth: Float = 0f + + /** + * @return the maximum width that the axis can take (in dp). + */ + /** + * Sets the maximum width that the axis can take (in dp). + */ + /** + * the maximum width that the axis can take (in dp). + * use Inifinity for disabling the maximum + * default: Float.POSITIVE_INFINITY (no maximum specified) + */ + var maxWidth: Float = Float.Companion.POSITIVE_INFINITY + + /** + * Enum that specifies the axis a DataSet should be plotted against, either LEFT or RIGHT. + * + * @author Philipp Jahoda + */ + enum class AxisDependency { + LEFT, RIGHT + } + + constructor() : super() { + // default left + this.axisDependency = AxisDependency.LEFT + this.mYOffset = 0f + } + + constructor(position: AxisDependency?) : super() { + this.axisDependency = position + this.mYOffset = 0f + } + + /** + * sets the position of the y-labels + */ + fun setPosition(pos: YAxisLabelPosition?) { + this.labelPosition = pos + } + + /** + * set this to true to enable drawing the top y-label entry. Disabling this can be helpful + * when the top y-label and + * left x-label interfere with each other. default: true + */ + fun setDrawTopYLabelEntry(enabled: Boolean) { + this.isDrawTopYLabelEntryEnabled = enabled + } + + /** + * This method is deprecated. + * Use setAxisMinimum(...) / setAxisMaximum(...) instead. + */ + @Deprecated("") + fun setStartAtZero(startAtZero: Boolean) { + if (startAtZero) axisMinimum = 0f + else resetAxisMinimum() + } + + /** + * Set this to true to draw the zero-line regardless of weather other + * grid-lines are enabled or not. Default: false + */ + fun setDrawZeroLine(mDrawZeroLine: Boolean) { + this.isDrawZeroLineEnabled = mDrawZeroLine + } + + var zeroLineWidth: Float + get() = mZeroLineWidth + /** + * Sets the width of the zero line in dp + */ + set(width) { + this.mZeroLineWidth = width.convertDpToPixel() + } + + /** + * This is for normal (not horizontal) charts horizontal spacing. + */ + fun getRequiredWidthSpace(p: Paint): Float { + p.setTextSize(mTextSize) + + val label = getLongestLabel(p) + var width = Utils.calcTextWidth(p, label).toFloat() + xOffset * 2f + + var minWidth = this.minWidth + var maxWidth = this.maxWidth + + if (minWidth > 0f) minWidth = minWidth.convertDpToPixel() + + if (maxWidth > 0f && maxWidth != Float.Companion.POSITIVE_INFINITY) maxWidth = maxWidth.convertDpToPixel() + + width = max(minWidth, min(width, if (maxWidth > 0.0) maxWidth else width)) + + return width + } + + /** + * This is for HorizontalBarChart vertical spacing. + */ + fun getRequiredHeightSpace(p: Paint): Float { + p.setTextSize(mTextSize) + + val label = getLongestLabel(p) + return Utils.calcTextHeight(p, label).toFloat() + yOffset * 2f + } + + /** + * Returns true if this axis needs horizontal offset, false if no offset is needed. + */ + fun needsOffset(): Boolean { + if (isEnabled && isDrawLabelsEnabled && this.labelPosition == YAxisLabelPosition.OUTSIDE_CHART) return true + else return false + } + + + public override fun calculate(dataMin: Float, dataMax: Float) { + var min = dataMin + var max = dataMax + + // Make sure max is greater than min + // Discussion: https://github.com/danielgindi/Charts/pull/3650#discussion_r221409991 + if (min > max) { + if (isAxisMaxCustom && isAxisMinCustom) { + val t = min + min = max + max = t + } else if (isAxisMaxCustom) { + min = if (max < 0f) max * 1.5f else max * 0.5f + } else if (isAxisMinCustom) { + max = if (min < 0f) min * 0.5f else min * 1.5f + } + } + + var range = abs(max - min) + + // in case all values are equal + if (range == 0f) { + max = max + 1f + min = min - 1f + } + + // recalculate + range = abs(max - min) + + // calc extra spacing + this.mAxisMinimum = if (isAxisMinCustom) this.mAxisMinimum else min - (range / 100f) * this.spaceBottom + this.mAxisMaximum = if (isAxisMaxCustom) this.mAxisMaximum else max + (range / 100f) * this.spaceTop + + this.mAxisRange = abs(this.mAxisMinimum - this.mAxisMaximum) + } +} diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRenderer.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRenderer.kt index 13c2408c49..310ed9c1db 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRenderer.kt +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRenderer.kt @@ -6,6 +6,8 @@ import android.graphics.Paint import android.graphics.Paint.Align import android.graphics.Path import android.graphics.RectF +import androidx.core.graphics.withClip +import androidx.core.graphics.withSave import com.github.mikephil.charting.components.LimitLine import com.github.mikephil.charting.components.LimitLine.LimitLabelPosition import com.github.mikephil.charting.components.XAxis @@ -16,8 +18,6 @@ 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 -import androidx.core.graphics.withClip -import androidx.core.graphics.withSave import com.github.mikephil.charting.utils.convertDpToPixel import kotlin.math.roundToInt @@ -102,21 +102,25 @@ open class XAxisRenderer( pointF.y = 1.0f drawLabels(canvas, viewPortHandler.contentTop() - yOffset, pointF) } + XAxisPosition.TOP_INSIDE -> { pointF.x = 0.5f pointF.y = 1.0f drawLabels(canvas, viewPortHandler.contentTop() + yOffset + xAxis.mLabelHeight, pointF) } + XAxisPosition.BOTTOM -> { pointF.x = 0.5f pointF.y = 0.0f drawLabels(canvas, viewPortHandler.contentBottom() + yOffset, pointF) } + XAxisPosition.BOTTOM_INSIDE -> { pointF.x = 0.5f pointF.y = 0.0f drawLabels(canvas, viewPortHandler.contentBottom() - yOffset - xAxis.mLabelHeight, pointF) } + else -> { // BOTH SIDED pointF.x = 0.5f pointF.y = 1.0f @@ -165,12 +169,12 @@ open class XAxisRenderer( var positions: FloatArray if (xAxis.isShowSpecificPositions) { - positions = FloatArray(xAxis.specificPositions.size * 2) - var i = 0 - while (i < positions.size) { - positions[i] = xAxis.specificPositions[i / 2] - i += 2 - } + positions = FloatArray(xAxis.specificPositions.size * 2) + var i = 0 + while (i < positions.size) { + positions[i] = xAxis.specificPositions[i / 2] + i += 2 + } } else { positions = FloatArray(xAxis.mEntryCount * 2) var i = 0 @@ -193,9 +197,9 @@ open class XAxisRenderer( if (viewPortHandler.isInBoundsX(x)) { val label = if (xAxis.isShowSpecificPositions) - xAxis.valueFormatter.getFormattedValue(xAxis.specificPositions[i / 2], xAxis) + xAxis.valueFormatter?.getFormattedValue(xAxis.specificPositions[i / 2], xAxis) else - xAxis.valueFormatter.getFormattedValue(xAxis.mEntries[i / 2], xAxis) + xAxis.valueFormatter?.getFormattedValue(xAxis.mEntries[i / 2], xAxis) if (xAxis.isAvoidFirstLastClippingEnabled) { // avoid clipping of the last @@ -347,7 +351,7 @@ open class XAxisRenderer( position[1] = 0f for (i in limitLines.indices) { - val limitLine = limitLines[i]!! + val limitLine = limitLines[i] if (!limitLine.isEnabled) continue @@ -393,10 +397,12 @@ open class XAxisRenderer( limitLinePaint ) } + LimitLabelPosition.RIGHT_BOTTOM -> { limitLinePaint.textAlign = Align.LEFT canvas.drawText(label, position[0] + xOffset, viewPortHandler.contentBottom() - yOffset, limitLinePaint) } + LimitLabelPosition.LEFT_TOP -> { limitLinePaint.textAlign = Align.RIGHT val labelLineHeight = Utils.calcTextHeight(limitLinePaint, label).toFloat() @@ -405,6 +411,7 @@ open class XAxisRenderer( limitLinePaint ) } + else -> { limitLinePaint.textAlign = Align.RIGHT canvas.drawText(label, position[0] - xOffset, viewPortHandler.contentBottom() - yOffset, limitLinePaint) diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererHorizontalBarChart.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererHorizontalBarChart.kt index e47e637ccf..cd29bcee04 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererHorizontalBarChart.kt +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererHorizontalBarChart.kt @@ -149,7 +149,7 @@ open class XAxisRendererHorizontalBarChart( val y = positions[i + 1] if (viewPortHandler.isInBoundsY(y)) { - val label = xAxis.valueFormatter.getFormattedValue(xAxis.mEntries[i / 2], xAxis) + val label = xAxis.valueFormatter?.getFormattedValue(xAxis.mEntries[i / 2], xAxis) drawLabel(canvas, label, pos, y, anchor, labelRotationAngleDegrees) } i += 2 @@ -215,7 +215,7 @@ open class XAxisRendererHorizontalBarChart( limitLinePath.reset() for (i in limitLines.indices) { - val limitLine = limitLines[i]!! + val limitLine = limitLines[i] if (!limitLine.isEnabled) continue diff --git a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererRadarChart.kt b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererRadarChart.kt index eb2a7e0729..a3df4c77b7 100644 --- a/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererRadarChart.kt +++ b/MPChartLib/src/main/java/com/github/mikephil/charting/renderer/XAxisRendererRadarChart.kt @@ -28,7 +28,7 @@ class XAxisRendererRadarChart(viewPortHandler: ViewPortHandler, xAxis: XAxis, pr val center = chart.centerOffsets val pOut = MPPointF.getInstance(0f, 0f) for (i in 0..