From d07ceda265830d585cda65d1132ebba283f2941c Mon Sep 17 00:00:00 2001 From: Philipp Jahoda Date: Fri, 24 Jul 2015 23:57:41 +0200 Subject: [PATCH] Added feature that allows the label-count to be exactly set and evenly distributed over the y-axis. --- .../mpchartexample/BarChartActivity.java | 4 +- .../mpchartexample/BarChartActivitySinus.java | 4 +- .../CandleStickChartActivity.java | 2 +- .../CubicLineChartActivity.java | 2 +- .../ListViewBarChartActivity.java | 4 +- .../mpchartexample/RadarChartActivitry.java | 2 +- .../StackedBarActivityNegative.java | 2 +- .../listviewitems/BarChartItem.java | 4 +- .../listviewitems/LineChartItem.java | 4 +- .../mikephil/charting/components/YAxis.java | 770 +++++++++--------- .../charting/renderer/YAxisRenderer.java | 475 +++++------ .../renderer/YAxisRendererRadarChart.java | 249 +++--- 12 files changed, 779 insertions(+), 743 deletions(-) diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivity.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivity.java index c483761e17..1db0e0232e 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivity.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivity.java @@ -96,7 +96,7 @@ protected void onCreate(Bundle savedInstanceState) { YAxis leftAxis = mChart.getAxisLeft(); leftAxis.setTypeface(mTf); - leftAxis.setLabelCount(8); + leftAxis.setLabelCount(8, false); leftAxis.setValueFormatter(custom); leftAxis.setPosition(YAxisLabelPosition.OUTSIDE_CHART); leftAxis.setSpaceTop(15f); @@ -104,7 +104,7 @@ protected void onCreate(Bundle savedInstanceState) { YAxis rightAxis = mChart.getAxisRight(); rightAxis.setDrawGridLines(false); rightAxis.setTypeface(mTf); - rightAxis.setLabelCount(8); + rightAxis.setLabelCount(8, false); rightAxis.setValueFormatter(custom); rightAxis.setSpaceTop(15f); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivitySinus.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivitySinus.java index 28b1ee56dd..5e53f2b147 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivitySinus.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/BarChartActivitySinus.java @@ -86,7 +86,7 @@ protected void onCreate(Bundle savedInstanceState) { YAxis leftAxis = mChart.getAxisLeft(); leftAxis.setTypeface(mTf); - leftAxis.setLabelCount(6); + leftAxis.setLabelCount(6, false); leftAxis.setStartAtZero(false); leftAxis.setAxisMinValue(-2.5f); leftAxis.setAxisMaxValue(2.5f); @@ -94,7 +94,7 @@ protected void onCreate(Bundle savedInstanceState) { YAxis rightAxis = mChart.getAxisRight(); rightAxis.setDrawGridLines(false); rightAxis.setTypeface(mTf); - rightAxis.setLabelCount(6); + rightAxis.setLabelCount(6, false); rightAxis.setStartAtZero(false); rightAxis.setAxisMinValue(-2.5f); rightAxis.setAxisMaxValue(2.5f); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CandleStickChartActivity.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CandleStickChartActivity.java index 07cf8ab1f9..384983f42b 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CandleStickChartActivity.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CandleStickChartActivity.java @@ -66,7 +66,7 @@ protected void onCreate(Bundle savedInstanceState) { YAxis leftAxis = mChart.getAxisLeft(); // leftAxis.setEnabled(false); - leftAxis.setLabelCount(7); + leftAxis.setLabelCount(7, false); leftAxis.setDrawGridLines(false); leftAxis.setDrawAxisLine(false); leftAxis.setStartAtZero(false); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CubicLineChartActivity.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CubicLineChartActivity.java index e86a1367f0..6b663c95ed 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CubicLineChartActivity.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/CubicLineChartActivity.java @@ -82,7 +82,7 @@ protected void onCreate(Bundle savedInstanceState) { YAxis y = mChart.getAxisLeft(); y.setTypeface(tf); - y.setLabelCount(5); + y.setLabelCount(5, false); y.setEnabled(false); mChart.getAxisRight().setEnabled(false); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/ListViewBarChartActivity.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/ListViewBarChartActivity.java index f2a66d1942..d314c3166f 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/ListViewBarChartActivity.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/ListViewBarChartActivity.java @@ -98,12 +98,12 @@ public View getView(int position, View convertView, ViewGroup parent) { YAxis leftAxis = holder.chart.getAxisLeft(); leftAxis.setTypeface(mTf); - leftAxis.setLabelCount(5); + leftAxis.setLabelCount(5, false); leftAxis.setSpaceTop(15f); YAxis rightAxis = holder.chart.getAxisRight(); rightAxis.setTypeface(mTf); - rightAxis.setLabelCount(5); + rightAxis.setLabelCount(5, false); rightAxis.setSpaceTop(15f); // set data diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivitry.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivitry.java index 524e7694c5..9660723760 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivitry.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/RadarChartActivitry.java @@ -61,7 +61,7 @@ protected void onCreate(Bundle savedInstanceState) { YAxis yAxis = mChart.getYAxis(); yAxis.setTypeface(tf); - yAxis.setLabelCount(5); + yAxis.setLabelCount(5, false); yAxis.setTextSize(9f); yAxis.setStartAtZero(true); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/StackedBarActivityNegative.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/StackedBarActivityNegative.java index 5b69a394ef..c242a7f2f8 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/StackedBarActivityNegative.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/StackedBarActivityNegative.java @@ -59,7 +59,7 @@ protected void onCreate(Bundle savedInstanceState) { mChart.getAxisRight().setStartAtZero(false); mChart.getAxisRight().setAxisMaxValue(25f); mChart.getAxisRight().setAxisMinValue(-25f); - mChart.getAxisRight().setLabelCount(7); + mChart.getAxisRight().setLabelCount(7, false); mChart.getAxisRight().setValueFormatter(new CustomFormatter()); mChart.getAxisRight().setTextSize(9f); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/listviewitems/BarChartItem.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/listviewitems/BarChartItem.java index d886c9d485..dabdb9a2a8 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/listviewitems/BarChartItem.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/listviewitems/BarChartItem.java @@ -60,12 +60,12 @@ public View getView(int position, View convertView, Context c) { YAxis leftAxis = holder.chart.getAxisLeft(); leftAxis.setTypeface(mTf); - leftAxis.setLabelCount(5); + leftAxis.setLabelCount(5, false); leftAxis.setSpaceTop(20f); YAxis rightAxis = holder.chart.getAxisRight(); rightAxis.setTypeface(mTf); - rightAxis.setLabelCount(5); + rightAxis.setLabelCount(5, false); rightAxis.setSpaceTop(20f); mChartData.setValueTypeface(mTf); diff --git a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/listviewitems/LineChartItem.java b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/listviewitems/LineChartItem.java index 16346251dd..1e2ab2301f 100644 --- a/MPChartExample/src/com/xxmassdeveloper/mpchartexample/listviewitems/LineChartItem.java +++ b/MPChartExample/src/com/xxmassdeveloper/mpchartexample/listviewitems/LineChartItem.java @@ -61,11 +61,11 @@ public View getView(int position, View convertView, Context c) { YAxis leftAxis = holder.chart.getAxisLeft(); leftAxis.setTypeface(mTf); - leftAxis.setLabelCount(5); + leftAxis.setLabelCount(5, false); YAxis rightAxis = holder.chart.getAxisRight(); rightAxis.setTypeface(mTf); - rightAxis.setLabelCount(5); + rightAxis.setLabelCount(5, false); rightAxis.setDrawGridLines(false); // set data diff --git a/MPChartLib/src/com/github/mikephil/charting/components/YAxis.java b/MPChartLib/src/com/github/mikephil/charting/components/YAxis.java index 79df15ac6f..12a93559c6 100644 --- a/MPChartLib/src/com/github/mikephil/charting/components/YAxis.java +++ b/MPChartLib/src/com/github/mikephil/charting/components/YAxis.java @@ -1,4 +1,3 @@ - package com.github.mikephil.charting.components; import android.graphics.Paint; @@ -8,404 +7,407 @@ import com.github.mikephil.charting.utils.ValueFormatter; /** - * 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 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 { - /** custom formatter that is used instead of the auto-formatter if set */ - protected ValueFormatter mValueFormatter; + /** custom formatter that is used instead of the auto-formatter if set */ + protected ValueFormatter mValueFormatter; + + /** the actual array of entries */ + public float[] mEntries = new float[] {}; - /** the actual array of entries */ - public float[] mEntries = new float[] {}; + /** the number of entries the legend contains */ + public int mEntryCount; - /** the number of entries the legend contains */ - public int mEntryCount; + /** the number of decimal digits to use */ + public int mDecimals; - /** the number of decimal digits to use */ - public int mDecimals; + /** the number of y-label entries the y-labels should have, default 6 */ + private int mLabelCount = 6; - /** the number of y-label entries the y-labels should have, default 6 */ - private int mLabelCount = 6; + /** indicates if the top y-label entry is drawn or not */ + private boolean mDrawTopYLabelEntry = true; - /** indicates if the top y-label entry is drawn or not */ - private boolean mDrawTopYLabelEntry = true; + /** if true, the y-labels show only the minimum and maximum value */ + protected boolean mShowOnlyMinMax = false; - /** if true, the y-labels show only the minimum and maximum value */ - protected boolean mShowOnlyMinMax = false; + /** flag that indicates if the axis is inverted or not */ + protected boolean mInverted = false; - /** flag that indicates if the axis is inverted or not */ - protected boolean mInverted = false; + /** if true, the y-label entries will always start at zero */ + protected boolean mStartAtZero = true; - /** if true, the y-label entries will always start at zero */ - protected boolean mStartAtZero = true; + /** if true, the set number of y-labels will be forced */ + protected boolean mForceLabels = false; /** custom minimum value this axis represents */ - protected float mCustomAxisMin = Float.NaN; - - /** custom maximum value this axis represents */ - protected float mCustomAxisMax = Float.NaN; - - /** - * 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; - - public float mAxisMaximum = 0f; - public float mAxisMinimum = 0f; - - /** the total range of values this axis covers */ - public float mAxisRange = 0f; - - /** the position of the y-labels relative to the chart */ - private YAxisLabelPosition mPosition = YAxisLabelPosition.OUTSIDE_CHART; - - /** 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 AxisDependency mAxisDependency; - - /** - * 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(); - this.mAxisDependency = AxisDependency.LEFT; - this.mYOffset = 0f; - } - - public YAxis(AxisDependency position) { - super(); - this.mAxisDependency = position; - this.mYOffset = 0f; - } - - public AxisDependency getAxisDependency() { - return mAxisDependency; - } - - /** - * returns the position of the y-labels - */ - public YAxisLabelPosition getLabelPosition() { - return mPosition; - } - - /** - * sets the position of the y-labels - * - * @param pos - */ - public void setPosition(YAxisLabelPosition pos) { - mPosition = pos; - } - - /** - * returns true if drawing the top y-axis label entry is enabled - * - * @return - */ - public boolean isDrawTopYLabelEntryEnabled() { - return mDrawTopYLabelEntry; - } - - /** - * 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 - * - * @param enabled - */ - public void setDrawTopYLabelEntry(boolean enabled) { - mDrawTopYLabelEntry = 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 and can only be - * approximated - * - * @param yCount - */ - public void setLabelCount(int yCount) { - - if (yCount > 25) - yCount = 25; - if (yCount < 2) - yCount = 2; - - mLabelCount = yCount; - } - - /** - * Returns the number of label entries the y-axis should have - * - * @return - */ - public int getLabelCount() { - return mLabelCount; - } - - /** - * If enabled, the YLabels will only show the minimum and maximum value of - * the chart. This will ignore/override the set label count. - * - * @param enabled - */ - public void setShowOnlyMinMax(boolean enabled) { - mShowOnlyMinMax = enabled; - } - - /** - * Returns true if showing only min and max value is enabled. - * - * @return - */ - public boolean isShowOnlyMinMaxEnabled() { - return mShowOnlyMinMax; - } - - /** - * 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. - * - * @param enabled - */ - public void setInverted(boolean enabled) { - mInverted = enabled; - } - - /** - * If this returns true, the y-axis is inverted. - * - * @return - */ - public boolean isInverted() { - return mInverted; - } - - /** - * enable this to force the y-axis labels to always start at zero - * - * @param enabled - */ - public void setStartAtZero(boolean enabled) { - this.mStartAtZero = enabled; - } - - /** - * returns true if the chart is set to start at zero, false otherwise - * - * @return - */ - public boolean isStartAtZeroEnabled() { - return mStartAtZero; - } + protected float mCustomAxisMin = Float.NaN; + + /** custom maximum value this axis represents */ + protected float mCustomAxisMax = Float.NaN; + + /** + * 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; + + public float mAxisMaximum = 0f; + public float mAxisMinimum = 0f; + + /** the total range of values this axis covers */ + public float mAxisRange = 0f; + + /** the position of the y-labels relative to the chart */ + private YAxisLabelPosition mPosition = YAxisLabelPosition.OUTSIDE_CHART; + + /** 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 AxisDependency mAxisDependency; + + /** + * 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(); + this.mAxisDependency = AxisDependency.LEFT; + this.mYOffset = 0f; + } + + public YAxis(AxisDependency position) { + super(); + this.mAxisDependency = position; + this.mYOffset = 0f; + } + + public AxisDependency getAxisDependency() { + return mAxisDependency; + } + + /** + * returns the position of the y-labels + */ + public YAxisLabelPosition getLabelPosition() { + return mPosition; + } + + /** + * sets the position of the y-labels + * + * @param pos + */ + public void setPosition(YAxisLabelPosition pos) { + mPosition = pos; + } + + /** + * returns true if drawing the top y-axis label entry is enabled + * + * @return + */ + public boolean isDrawTopYLabelEntryEnabled() { + return mDrawTopYLabelEntry; + } + + /** + * 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 + * + * @param enabled + */ + public void setDrawTopYLabelEntry(boolean enabled) { + mDrawTopYLabelEntry = 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 sould 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) { + + if (count > 25) + count = 25; + if (count < 2) + count = 2; + + mLabelCount = count; + mForceLabels = force; + } + + /** + * Returns the number of label entries the y-axis should have + * + * @return + */ + public int getLabelCount() { + return mLabelCount; + } + + /** + * Returns true if focing the y-label count is enabled. Default: false + * + * @return + */ + public boolean isForceLabelsEnabled() { + return mForceLabels; + } + + /** + * If enabled, the YLabels will only show the minimum and maximum value of the chart. This will ignore/override the + * set label count. + * + * @param enabled + */ + public void setShowOnlyMinMax(boolean enabled) { + mShowOnlyMinMax = enabled; + } + + /** + * Returns true if showing only min and max value is enabled. + * + * @return + */ + public boolean isShowOnlyMinMaxEnabled() { + return mShowOnlyMinMax; + } + + /** + * 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. + * + * @param enabled + */ + public void setInverted(boolean enabled) { + mInverted = enabled; + } + + /** + * If this returns true, the y-axis is inverted. + * + * @return + */ + public boolean isInverted() { + return mInverted; + } + + /** + * enable this to force the y-axis labels to always start at zero + * + * @param enabled + */ + public void setStartAtZero(boolean enabled) { + this.mStartAtZero = enabled; + } + + /** + * returns true if the chart is set to start at zero, false otherwise + * + * @return + */ + public boolean isStartAtZeroEnabled() { + return mStartAtZero; + } public float getAxisMinValue() { - 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. - * - * @param min - */ - public void setAxisMinValue(float min) { - mCustomAxisMin = min; - } - - /** - * By calling this method, any custom minimum value that has been previously - * set is reseted, and the calculation is done automatically. - */ - public void resetAxisMinValue() { - mCustomAxisMin = Float.NaN; - } - - public float getAxisMaxValue() { - return mCustomAxisMax; - } - - /** - * 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. - * - * @param max - */ - public void setAxisMaxValue(float max) { - mCustomAxisMax = max; - } - - /** - * By calling this method, any custom maximum value that has been previously - * set is reseted, and the calculation is done automatically. - */ - public void resetAxisMaxValue() { - mCustomAxisMax = Float.NaN; - } - - /** - * Sets the top axis space in percent of the full range. Default 10f - * - * @param percent - */ - public void setSpaceTop(float percent) { - mSpacePercentTop = percent; - } - - /** - * Returns the top axis space in percent of the full range. Default 10f - * - * @return - */ - public float getSpaceTop() { - return mSpacePercentTop; - } - - /** - * Sets the bottom axis space in percent of the full range. Default 10f - * - * @param percent - */ - public void setSpaceBottom(float percent) { - mSpacePercentBottom = percent; - } - - /** - * Returns the bottom axis space in percent of the full range. Default 10f - * - * @return - */ - public float getSpaceBottom() { - return mSpacePercentBottom; - } - - public float getRequiredWidthSpace(Paint p) { - - p.setTextSize(mTextSize); - - String label = getLongestLabel(); - return (float) Utils.calcTextWidth(p, label) + getXOffset() * 2f; - } - - public float getRequiredHeightSpace(Paint p) { - - p.setTextSize(mTextSize); - - String label = getLongestLabel(); - return (float) Utils.calcTextHeight(p, label) + Utils.convertDpToPixel(2.5f) * 2f + getYOffset(); - } - - @Override - public String getLongestLabel() { - - String longest = ""; - - for (int i = 0; i < mEntries.length; i++) { - String text = getFormattedLabel(i); - - if (longest.length() < text.length()) - longest = text; - } - - return longest; - } - - /** - * Returns the formatted y-label at the specified index. This will either - * use the auto-formatter or the custom formatter (if one is set). - * - * @param index - * @return - */ - public String getFormattedLabel(int index) { - - if (index < 0 || index >= mEntries.length) - return ""; - else - return getValueFormatter().getFormattedValue(mEntries[index]); - } - - /** - * Sets the formatter to be used for drawing the values inside the chart. 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. - * - * @param f - */ - public void setValueFormatter(ValueFormatter f) { - - if (f == null) - return; - else - mValueFormatter = f; - } - - /** - * Returns the formatter used for drawing the values inside the chart. - * - * @return - */ - public ValueFormatter getValueFormatter() { - return mValueFormatter; - } - - /** - * If this component has no ValueFormatter or is only equipped with the - * default one (no custom set), return true. - * - * @return - */ - public boolean needsDefaultFormatter() { - if (mValueFormatter == null) - return true; - if (mValueFormatter instanceof DefaultValueFormatter) - return true; - - return false; - } - - /** - * Returns true if this axis needs horizontal offset, false if no offset is - * needed. - * - * @return - */ - public boolean needsOffset() { - if (isEnabled() && isDrawLabelsEnabled() - && getLabelPosition() == YAxisLabelPosition.OUTSIDE_CHART) - return true; - else - return false; - } + 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. + * + * @param min + */ + public void setAxisMinValue(float min) { + mCustomAxisMin = min; + } + + /** + * By calling this method, any custom minimum value that has been previously set is reseted, and the calculation is + * done automatically. + */ + public void resetAxisMinValue() { + mCustomAxisMin = Float.NaN; + } + + public float getAxisMaxValue() { + return mCustomAxisMax; + } + + /** + * 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. + * + * @param max + */ + public void setAxisMaxValue(float max) { + mCustomAxisMax = max; + } + + /** + * By calling this method, any custom maximum value that has been previously set is reseted, and the calculation is + * done automatically. + */ + public void resetAxisMaxValue() { + mCustomAxisMax = Float.NaN; + } + + /** + * Sets the top axis space in percent of the full range. Default 10f + * + * @param percent + */ + public void setSpaceTop(float percent) { + mSpacePercentTop = percent; + } + + /** + * Returns the top axis space in percent of the full range. Default 10f + * + * @return + */ + public float getSpaceTop() { + return mSpacePercentTop; + } + + /** + * Sets the bottom axis space in percent of the full range. Default 10f + * + * @param percent + */ + public void setSpaceBottom(float percent) { + mSpacePercentBottom = percent; + } + + /** + * Returns the bottom axis space in percent of the full range. Default 10f + * + * @return + */ + public float getSpaceBottom() { + return mSpacePercentBottom; + } + + public float getRequiredWidthSpace(Paint p) { + + p.setTextSize(mTextSize); + + String label = getLongestLabel(); + return (float) Utils.calcTextWidth(p, label) + getXOffset() * 2f; + } + + public float getRequiredHeightSpace(Paint p) { + + p.setTextSize(mTextSize); + + String label = getLongestLabel(); + return (float) Utils.calcTextHeight(p, label) + Utils.convertDpToPixel(2.5f) * 2f + getYOffset(); + } + + @Override + public String getLongestLabel() { + + String longest = ""; + + for (int i = 0; i < mEntries.length; i++) { + String text = getFormattedLabel(i); + + if (longest.length() < text.length()) + longest = text; + } + + return longest; + } + + /** + * Returns the formatted y-label at the specified index. This will either use the auto-formatter or the custom + * formatter (if one is set). + * + * @param index + * @return + */ + public String getFormattedLabel(int index) { + + if (index < 0 || index >= mEntries.length) + return ""; + else + return getValueFormatter().getFormattedValue(mEntries[index]); + } + + /** + * Sets the formatter to be used for drawing the values inside the chart. 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. + * + * @param f + */ + public void setValueFormatter(ValueFormatter f) { + + if (f == null) + return; + else + mValueFormatter = f; + } + + /** + * Returns the formatter used for drawing the values inside the chart. + * + * @return + */ + public ValueFormatter getValueFormatter() { + return mValueFormatter; + } + + /** + * If this component has no ValueFormatter or is only equipped with the default one (no custom set), return true. + * + * @return + */ + public boolean needsDefaultFormatter() { + if (mValueFormatter == null) + return true; + if (mValueFormatter instanceof DefaultValueFormatter) + return true; + + return false; + } + + /** + * Returns true if this axis needs horizontal offset, false if no offset is needed. + * + * @return + */ + public boolean needsOffset() { + if (isEnabled() && isDrawLabelsEnabled() && getLabelPosition() == YAxisLabelPosition.OUTSIDE_CHART) + return true; + else + return false; + } } diff --git a/MPChartLib/src/com/github/mikephil/charting/renderer/YAxisRenderer.java b/MPChartLib/src/com/github/mikephil/charting/renderer/YAxisRenderer.java index d76eefe272..b437eca7fb 100644 --- a/MPChartLib/src/com/github/mikephil/charting/renderer/YAxisRenderer.java +++ b/MPChartLib/src/com/github/mikephil/charting/renderer/YAxisRenderer.java @@ -1,4 +1,3 @@ - package com.github.mikephil.charting.renderer; import android.graphics.Canvas; @@ -23,65 +22,64 @@ public class YAxisRenderer extends AxisRenderer { protected YAxis mYAxis; - public YAxisRenderer(ViewPortHandler viewPortHandler, YAxis yAxis, Transformer trans) { - super(viewPortHandler, trans); - - this.mYAxis = yAxis; - - mAxisLabelPaint.setColor(Color.BLACK); - mAxisLabelPaint.setTextSize(Utils.convertDpToPixel(10f)); - } - - /** - * Computes the axis values. - * - * @param yMin - the minimum y-value in the data object for this axis - * @param yMax - the maximum y-value in the data object for this axis - */ - public void computeAxis(float yMin, float yMax) { - - // calculate the starting and entry point of the y-labels (depending on - // zoom / contentrect bounds) - if (mViewPortHandler.contentWidth() > 10 && !mViewPortHandler.isFullyZoomedOutY()) { - - PointD p1 = mTrans.getValuesByTouchPoint(mViewPortHandler.contentLeft(), - mViewPortHandler.contentTop()); - PointD p2 = mTrans.getValuesByTouchPoint(mViewPortHandler.contentLeft(), - mViewPortHandler.contentBottom()); - - if (!mYAxis.isInverted()) { - yMin = (float) p2.y; - yMax = (float) p1.y; - } else { - - yMin = (float) p1.y; - yMax = (float) p2.y; - } - } - - computeAxisValues(yMin, yMax); - } - - /** - * Sets up the y-axis labels. Computes the desired number of labels between - * the two given extremes. Unlike the papareXLabels() method, this method - * needs to be called upon every refresh of the view. - * - * @return - */ - protected void computeAxisValues(float min, float max) { - - float yMin = min; - float yMax = max; - - int labelCount = mYAxis.getLabelCount(); - double range = Math.abs(yMax - yMin); - - if (labelCount == 0 || range <= 0) { - mYAxis.mEntries = new float[] {}; - mYAxis.mEntryCount = 0; - return; - } + public YAxisRenderer(ViewPortHandler viewPortHandler, YAxis yAxis, Transformer trans) { + super(viewPortHandler, trans); + + this.mYAxis = yAxis; + + mAxisLabelPaint.setColor(Color.BLACK); + mAxisLabelPaint.setTextSize(Utils.convertDpToPixel(10f)); + } + + /** + * Computes the axis values. + * + * @param yMin + * - the minimum y-value in the data object for this axis + * @param yMax + * - the maximum y-value in the data object for this axis + */ + public void computeAxis(float yMin, float yMax) { + + // calculate the starting and entry point of the y-labels (depending on + // zoom / contentrect bounds) + if (mViewPortHandler.contentWidth() > 10 && !mViewPortHandler.isFullyZoomedOutY()) { + + PointD p1 = mTrans.getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop()); + PointD p2 = mTrans.getValuesByTouchPoint(mViewPortHandler.contentLeft(), mViewPortHandler.contentBottom()); + + if (!mYAxis.isInverted()) { + yMin = (float) p2.y; + yMax = (float) p1.y; + } else { + + yMin = (float) p1.y; + yMax = (float) p2.y; + } + } + + computeAxisValues(yMin, yMax); + } + + /** + * Sets up the y-axis labels. Computes the desired number of labels between the two given extremes. Unlike the + * papareXLabels() method, this method needs to be called upon every refresh of the view. + * + * @return + */ + protected void computeAxisValues(float min, float max) { + + float yMin = min; + float yMax = max; + + int labelCount = mYAxis.getLabelCount(); + double range = Math.abs(yMax - yMin); + + if (labelCount == 0 || range <= 0) { + mYAxis.mEntries = new float[] {}; + mYAxis.mEntryCount = 0; + return; + } double rawInterval = range / labelCount; double interval = Utils.roundToNextSignificant(rawInterval); @@ -93,238 +91,253 @@ protected void computeAxisValues(float min, float max) { interval = Math.floor(10 * intervalMagnitude); } - // if the labels should only show min and max - if (mYAxis.isShowOnlyMinMaxEnabled()) { + // force label count + if (mYAxis.isForceLabelsEnabled()) { - mYAxis.mEntryCount = 2; - mYAxis.mEntries = new float[2]; - mYAxis.mEntries[0] = yMin; - mYAxis.mEntries[1] = yMax; + float step = (float) range / (float) (labelCount-1); + mYAxis.mEntryCount = labelCount; - } else { + if (mYAxis.mEntries.length < labelCount) { + // Ensure stops contains at least numStops elements. + mYAxis.mEntries = new float[labelCount]; + } - double first = Math.ceil(yMin / interval) * interval; - double last = Utils.nextUp(Math.floor(yMax / interval) * interval); + float v = min; - double f; - int i; - int n = 0; - for (f = first; f <= last; f += interval) { - ++n; + for(int i = 0; i < labelCount; i++) { + mYAxis.mEntries[i] = v; + v += step; } - mYAxis.mEntryCount = n; + // no forced count + } else { - if (mYAxis.mEntries.length < n) { - // Ensure stops contains at least numStops elements. - mYAxis.mEntries = new float[n]; - } + // if the labels should only show min and max + if (mYAxis.isShowOnlyMinMaxEnabled()) { - for (f = first, i = 0; i < n; f += interval, ++i) { - mYAxis.mEntries[i] = (float) f; - } - } + mYAxis.mEntryCount = 2; + mYAxis.mEntries = new float[2]; + mYAxis.mEntries[0] = yMin; + mYAxis.mEntries[1] = yMax; + + } else { + + double first = Math.ceil(yMin / interval) * interval; + double last = Utils.nextUp(Math.floor(yMax / interval) * interval); + + double f; + int i; + int n = 0; + for (f = first; f <= last; f += interval) { + ++n; + } + + mYAxis.mEntryCount = n; + + if (mYAxis.mEntries.length < n) { + // Ensure stops contains at least numStops elements. + mYAxis.mEntries = new float[n]; + } + for (f = first, i = 0; i < n; f += interval, ++i) { + mYAxis.mEntries[i] = (float) f; + } + } + } + + // set decimals if (interval < 1) { mYAxis.mDecimals = (int) Math.ceil(-Math.log10(interval)); } else { mYAxis.mDecimals = 0; } - } + } - /** - * draws the y-axis labels to the screen - */ - @Override - public void renderAxisLabels(Canvas c) { + /** + * draws the y-axis labels to the screen + */ + @Override + public void renderAxisLabels(Canvas c) { - if (!mYAxis.isEnabled() || !mYAxis.isDrawLabelsEnabled()) - return; + if (!mYAxis.isEnabled() || !mYAxis.isDrawLabelsEnabled()) + return; - float[] positions = new float[mYAxis.mEntryCount * 2]; + float[] positions = new float[mYAxis.mEntryCount * 2]; - for (int i = 0; i < positions.length; i += 2) { - // only fill y values, x values are not needed since the y-labels - // are - // static on the x-axis - positions[i + 1] = mYAxis.mEntries[i / 2]; - } + for (int i = 0; i < positions.length; i += 2) { + // only fill y values, x values are not needed since the y-labels + // are + // static on the x-axis + positions[i + 1] = mYAxis.mEntries[i / 2]; + } - mTrans.pointValuesToPixel(positions); + mTrans.pointValuesToPixel(positions); - mAxisLabelPaint.setTypeface(mYAxis.getTypeface()); - mAxisLabelPaint.setTextSize(mYAxis.getTextSize()); - mAxisLabelPaint.setColor(mYAxis.getTextColor()); + mAxisLabelPaint.setTypeface(mYAxis.getTypeface()); + mAxisLabelPaint.setTextSize(mYAxis.getTextSize()); + mAxisLabelPaint.setColor(mYAxis.getTextColor()); - float xoffset = mYAxis.getXOffset(); - float yoffset = Utils.calcTextHeight(mAxisLabelPaint, "A") / 2.5f + mYAxis.getYOffset(); + float xoffset = mYAxis.getXOffset(); + float yoffset = Utils.calcTextHeight(mAxisLabelPaint, "A") / 2.5f + mYAxis.getYOffset(); - AxisDependency dependency = mYAxis.getAxisDependency(); - YAxisLabelPosition labelPosition = mYAxis.getLabelPosition(); + AxisDependency dependency = mYAxis.getAxisDependency(); + YAxisLabelPosition labelPosition = mYAxis.getLabelPosition(); - float xPos = 0f; + float xPos = 0f; - if (dependency == AxisDependency.LEFT) { + if (dependency == AxisDependency.LEFT) { - if (labelPosition == YAxisLabelPosition.OUTSIDE_CHART) { - mAxisLabelPaint.setTextAlign(Align.RIGHT); - xPos = mViewPortHandler.offsetLeft() - xoffset; - } else { - mAxisLabelPaint.setTextAlign(Align.LEFT); - xPos = mViewPortHandler.offsetLeft() + xoffset; - } + if (labelPosition == YAxisLabelPosition.OUTSIDE_CHART) { + mAxisLabelPaint.setTextAlign(Align.RIGHT); + xPos = mViewPortHandler.offsetLeft() - xoffset; + } else { + mAxisLabelPaint.setTextAlign(Align.LEFT); + xPos = mViewPortHandler.offsetLeft() + xoffset; + } - } else { + } else { - if (labelPosition == YAxisLabelPosition.OUTSIDE_CHART) { - mAxisLabelPaint.setTextAlign(Align.LEFT); - xPos = mViewPortHandler.contentRight() + xoffset; - } else { - mAxisLabelPaint.setTextAlign(Align.RIGHT); - xPos = mViewPortHandler.contentRight() - xoffset; - } - } + if (labelPosition == YAxisLabelPosition.OUTSIDE_CHART) { + mAxisLabelPaint.setTextAlign(Align.LEFT); + xPos = mViewPortHandler.contentRight() + xoffset; + } else { + mAxisLabelPaint.setTextAlign(Align.RIGHT); + xPos = mViewPortHandler.contentRight() - xoffset; + } + } - drawYLabels(c, xPos, positions, yoffset); - } + drawYLabels(c, xPos, positions, yoffset); + } - @Override - public void renderAxisLine(Canvas c) { + @Override + public void renderAxisLine(Canvas c) { - if (!mYAxis.isEnabled() || !mYAxis.isDrawAxisLineEnabled()) - return; + if (!mYAxis.isEnabled() || !mYAxis.isDrawAxisLineEnabled()) + return; - mAxisLinePaint.setColor(mYAxis.getAxisLineColor()); - mAxisLinePaint.setStrokeWidth(mYAxis.getAxisLineWidth()); + mAxisLinePaint.setColor(mYAxis.getAxisLineColor()); + mAxisLinePaint.setStrokeWidth(mYAxis.getAxisLineWidth()); - if (mYAxis.getAxisDependency() == AxisDependency.LEFT) { - c.drawLine(mViewPortHandler.contentLeft(), - mViewPortHandler.contentTop(), mViewPortHandler.contentLeft(), - mViewPortHandler.contentBottom(), mAxisLinePaint); - } else { - c.drawLine(mViewPortHandler.contentRight(), - mViewPortHandler.contentTop(), mViewPortHandler.contentRight(), - mViewPortHandler.contentBottom(), mAxisLinePaint); - } - } + if (mYAxis.getAxisDependency() == AxisDependency.LEFT) { + c.drawLine(mViewPortHandler.contentLeft(), mViewPortHandler.contentTop(), mViewPortHandler.contentLeft(), + mViewPortHandler.contentBottom(), mAxisLinePaint); + } else { + c.drawLine(mViewPortHandler.contentRight(), mViewPortHandler.contentTop(), mViewPortHandler.contentRight(), + mViewPortHandler.contentBottom(), mAxisLinePaint); + } + } - /** - * draws the y-labels on the specified x-position - * - * @param fixedPosition - * @param positions - */ - protected void drawYLabels(Canvas c, float fixedPosition, float[] positions, float offset) { + /** + * draws the y-labels on the specified x-position + * + * @param fixedPosition + * @param positions + */ + protected void drawYLabels(Canvas c, float fixedPosition, float[] positions, float offset) { - // draw - for (int i = 0; i < mYAxis.mEntryCount; i++) { + // draw + for (int i = 0; i < mYAxis.mEntryCount; i++) { - String text = mYAxis.getFormattedLabel(i); + String text = mYAxis.getFormattedLabel(i); - if (!mYAxis.isDrawTopYLabelEntryEnabled() && i >= mYAxis.mEntryCount - 1) - return; + if (!mYAxis.isDrawTopYLabelEntryEnabled() && i >= mYAxis.mEntryCount - 1) + return; - c.drawText(text, fixedPosition, positions[i * 2 + 1] + offset, mAxisLabelPaint); - } - } + c.drawText(text, fixedPosition, positions[i * 2 + 1] + offset, mAxisLabelPaint); + } + } - @Override - public void renderGridLines(Canvas c) { + @Override + public void renderGridLines(Canvas c) { - if (!mYAxis.isDrawGridLinesEnabled() || !mYAxis.isEnabled()) - return; + if (!mYAxis.isDrawGridLinesEnabled() || !mYAxis.isEnabled()) + return; - // pre alloc - float[] position = new float[2]; + // pre alloc + float[] position = new float[2]; - mGridPaint.setColor(mYAxis.getGridColor()); - mGridPaint.setStrokeWidth(mYAxis.getGridLineWidth()); - mGridPaint.setPathEffect(mYAxis.getGridDashPathEffect()); + mGridPaint.setColor(mYAxis.getGridColor()); + mGridPaint.setStrokeWidth(mYAxis.getGridLineWidth()); + mGridPaint.setPathEffect(mYAxis.getGridDashPathEffect()); - Path gridLinePath = new Path(); + Path gridLinePath = new Path(); - // draw the horizontal grid - for (int i = 0; i < mYAxis.mEntryCount; i++) { + // draw the horizontal grid + for (int i = 0; i < mYAxis.mEntryCount; i++) { - position[1] = mYAxis.mEntries[i]; - mTrans.pointValuesToPixel(position); + position[1] = mYAxis.mEntries[i]; + mTrans.pointValuesToPixel(position); - gridLinePath.moveTo(mViewPortHandler.offsetLeft(), position[1]); - gridLinePath.lineTo(mViewPortHandler.contentRight(), - position[1]); + gridLinePath.moveTo(mViewPortHandler.offsetLeft(), position[1]); + gridLinePath.lineTo(mViewPortHandler.contentRight(), position[1]); - // draw a path because lines don't support dashing on lower android versions - c.drawPath(gridLinePath, mGridPaint); + // draw a path because lines don't support dashing on lower android versions + c.drawPath(gridLinePath, mGridPaint); - gridLinePath.reset(); - } - } - - /** - * Draws the LimitLines associated with this axis to the screen. - * - * @param c - */ - @Override + gridLinePath.reset(); + } + } + + /** + * Draws the LimitLines associated with this axis to the screen. + * + * @param c + */ + @Override public void renderLimitLines(Canvas c) { - List limitLines = mYAxis.getLimitLines(); + List limitLines = mYAxis.getLimitLines(); - if (limitLines == null || limitLines.size() <= 0) - return; + if (limitLines == null || limitLines.size() <= 0) + return; - float[] pts = new float[2]; - Path limitLinePath = new Path(); + float[] pts = new float[2]; + Path limitLinePath = new Path(); - for (int i = 0; i < limitLines.size(); i++) { + for (int i = 0; i < limitLines.size(); i++) { - LimitLine l = limitLines.get(i); - - mLimitLinePaint.setStyle(Paint.Style.STROKE); - mLimitLinePaint.setColor(l.getLineColor()); - mLimitLinePaint.setStrokeWidth(l.getLineWidth()); - mLimitLinePaint.setPathEffect(l.getDashPathEffect()); + LimitLine l = limitLines.get(i); - pts[1] = l.getLimit(); + mLimitLinePaint.setStyle(Paint.Style.STROKE); + mLimitLinePaint.setColor(l.getLineColor()); + mLimitLinePaint.setStrokeWidth(l.getLineWidth()); + mLimitLinePaint.setPathEffect(l.getDashPathEffect()); - mTrans.pointValuesToPixel(pts); + pts[1] = l.getLimit(); - limitLinePath.moveTo(mViewPortHandler.contentLeft(), pts[1]); - limitLinePath.lineTo(mViewPortHandler.contentRight(), pts[1]); - - c.drawPath(limitLinePath, mLimitLinePaint); - limitLinePath.reset(); - // c.drawLines(pts, mLimitLinePaint); + mTrans.pointValuesToPixel(pts); - String label = l.getLabel(); + limitLinePath.moveTo(mViewPortHandler.contentLeft(), pts[1]); + limitLinePath.lineTo(mViewPortHandler.contentRight(), pts[1]); - // if drawing the limit-value label is enabled - if (label != null && !label.equals("")) { + c.drawPath(limitLinePath, mLimitLinePaint); + limitLinePath.reset(); + // c.drawLines(pts, mLimitLinePaint); - float xOffset = Utils.convertDpToPixel(4f); - float yOffset = l.getLineWidth() + Utils.calcTextHeight(mLimitLinePaint, label) - / 2f; + String label = l.getLabel(); - mLimitLinePaint.setStyle(l.getTextStyle()); - mLimitLinePaint.setPathEffect(null); - mLimitLinePaint.setColor(l.getTextColor()); - mLimitLinePaint.setStrokeWidth(0.5f); - mLimitLinePaint.setTextSize(l.getTextSize()); + // if drawing the limit-value label is enabled + if (label != null && !label.equals("")) { - if (l.getLabelPosition() == LimitLabelPosition.POS_RIGHT) { + float xOffset = Utils.convertDpToPixel(4f); + float yOffset = l.getLineWidth() + Utils.calcTextHeight(mLimitLinePaint, label) / 2f; - mLimitLinePaint.setTextAlign(Align.RIGHT); - c.drawText(label, mViewPortHandler.contentRight() - - xOffset, - pts[1] - yOffset, mLimitLinePaint); + mLimitLinePaint.setStyle(l.getTextStyle()); + mLimitLinePaint.setPathEffect(null); + mLimitLinePaint.setColor(l.getTextColor()); + mLimitLinePaint.setStrokeWidth(0.5f); + mLimitLinePaint.setTextSize(l.getTextSize()); - } else { - mLimitLinePaint.setTextAlign(Align.LEFT); - c.drawText(label, mViewPortHandler.offsetLeft() - + xOffset, - pts[1] - yOffset, mLimitLinePaint); - } - } - } - } + if (l.getLabelPosition() == LimitLabelPosition.POS_RIGHT) { + + mLimitLinePaint.setTextAlign(Align.RIGHT); + c.drawText(label, mViewPortHandler.contentRight() - xOffset, pts[1] - yOffset, mLimitLinePaint); + + } else { + mLimitLinePaint.setTextAlign(Align.LEFT); + c.drawText(label, mViewPortHandler.offsetLeft() + xOffset, pts[1] - yOffset, mLimitLinePaint); + } + } + } + } } diff --git a/MPChartLib/src/com/github/mikephil/charting/renderer/YAxisRendererRadarChart.java b/MPChartLib/src/com/github/mikephil/charting/renderer/YAxisRendererRadarChart.java index bae51e0ebe..a2399fcb6c 100644 --- a/MPChartLib/src/com/github/mikephil/charting/renderer/YAxisRendererRadarChart.java +++ b/MPChartLib/src/com/github/mikephil/charting/renderer/YAxisRendererRadarChart.java @@ -1,4 +1,3 @@ - package com.github.mikephil.charting.renderer; import android.graphics.Canvas; @@ -15,163 +14,185 @@ public class YAxisRendererRadarChart extends YAxisRenderer { - private RadarChart mChart; + private RadarChart mChart; + + public YAxisRendererRadarChart(ViewPortHandler viewPortHandler, YAxis yAxis, RadarChart chart) { + super(viewPortHandler, yAxis, null); + + this.mChart = chart; + } + + @Override + public void computeAxis(float yMin, float yMax) { + computeAxisValues(yMin, yMax); + } + + @Override + protected void computeAxisValues(float min, float max) { + float yMin = min; + float yMax = max; + + int labelCount = mYAxis.getLabelCount(); + double range = Math.abs(yMax - yMin); + + if (labelCount == 0 || range <= 0) { + mYAxis.mEntries = new float[] {}; + mYAxis.mEntryCount = 0; + return; + } + + double rawInterval = range / labelCount; + double interval = Utils.roundToNextSignificant(rawInterval); + double intervalMagnitude = Math.pow(10, (int) Math.log10(interval)); + int intervalSigDigit = (int) (interval / intervalMagnitude); + if (intervalSigDigit > 5) { + // Use one order of magnitude higher, to avoid intervals like 0.9 or + // 90 + interval = Math.floor(10 * intervalMagnitude); + } - public YAxisRendererRadarChart(ViewPortHandler viewPortHandler, YAxis yAxis, RadarChart chart) { - super(viewPortHandler, yAxis, null); + // force label count + if (mYAxis.isForceLabelsEnabled()) { - this.mChart = chart; - } + float step = (float) range / (float) (labelCount-1); + mYAxis.mEntryCount = labelCount; - @Override - public void computeAxis(float yMin, float yMax) { - computeAxisValues(yMin, yMax); - } + if (mYAxis.mEntries.length < labelCount) { + // Ensure stops contains at least numStops elements. + mYAxis.mEntries = new float[labelCount]; + } - @Override - protected void computeAxisValues(float min, float max) { - float yMin = min; - float yMax = max; + float v = min; - int labelCount = mYAxis.getLabelCount(); - double range = Math.abs(yMax - yMin); + for (int i = 0; i < labelCount; i++) { + mYAxis.mEntries[i] = v; + v += step; + } - if (labelCount == 0 || range <= 0) { - mYAxis.mEntries = new float[] {}; - mYAxis.mEntryCount = 0; - return; - } + // no forced count + } else { - double rawInterval = range / labelCount; - double interval = Utils.roundToNextSignificant(rawInterval); - double intervalMagnitude = Math.pow(10, (int) Math.log10(interval)); - int intervalSigDigit = (int) (interval / intervalMagnitude); - if (intervalSigDigit > 5) { - // Use one order of magnitude higher, to avoid intervals like 0.9 or - // 90 - interval = Math.floor(10 * intervalMagnitude); - } + // if the labels should only show min and max + if (mYAxis.isShowOnlyMinMaxEnabled()) { - // if the labels should only show min and max - if (mYAxis.isShowOnlyMinMaxEnabled()) { + mYAxis.mEntryCount = 2; + mYAxis.mEntries = new float[2]; + mYAxis.mEntries[0] = yMin; + mYAxis.mEntries[1] = yMax; - mYAxis.mEntryCount = 2; - mYAxis.mEntries = new float[2]; - mYAxis.mEntries[0] = yMin; - mYAxis.mEntries[1] = yMax; + } else { - } else { + double first = Math.ceil(yMin / interval) * interval; - double first = Math.ceil(yMin / interval) * interval; + if (first == 0.0) // Fix for IEEE negative zero case (Where value == -0.0, and 0.0 == -0.0) + first = 0.0; - if (first == 0.0) // Fix for IEEE negative zero case (Where value == -0.0, and 0.0 == -0.0) - first = 0.0; + double last = Utils.nextUp(Math.floor(yMax / interval) * interval); - double last = Utils.nextUp(Math.floor(yMax / interval) * interval); + double f; + int i; + int n = 0; + for (f = first; f <= last; f += interval) { + ++n; + } - double f; - int i; - int n = 0; - for (f = first; f <= last; f += interval) { - ++n; - } + if (Float.isNaN(mYAxis.getAxisMaxValue())) + n += 1; - if (Float.isNaN(mYAxis.getAxisMaxValue())) - n += 1; - - mYAxis.mEntryCount = n; + mYAxis.mEntryCount = n; - if (mYAxis.mEntries.length < n) { - // Ensure stops contains at least numStops elements. - mYAxis.mEntries = new float[n]; - } + if (mYAxis.mEntries.length < n) { + // Ensure stops contains at least numStops elements. + mYAxis.mEntries = new float[n]; + } - for (f = first, i = 0; i < n; f += interval, ++i) { - mYAxis.mEntries[i] = (float) f; - } - } + for (f = first, i = 0; i < n; f += interval, ++i) { + mYAxis.mEntries[i] = (float) f; + } + } + } - if (interval < 1) { - mYAxis.mDecimals = (int) Math.ceil(-Math.log10(interval)); - } else { - mYAxis.mDecimals = 0; - } + if (interval < 1) { + mYAxis.mDecimals = (int) Math.ceil(-Math.log10(interval)); + } else { + mYAxis.mDecimals = 0; + } - mYAxis.mAxisMaximum = mYAxis.mEntries[mYAxis.mEntryCount - 1]; - mYAxis.mAxisRange = Math.abs(mYAxis.mAxisMaximum - mYAxis.mAxisMinimum); - } + mYAxis.mAxisMaximum = mYAxis.mEntries[mYAxis.mEntryCount - 1]; + mYAxis.mAxisRange = Math.abs(mYAxis.mAxisMaximum - mYAxis.mAxisMinimum); + } - @Override - public void renderAxisLabels(Canvas c) { + @Override + public void renderAxisLabels(Canvas c) { - if (!mYAxis.isEnabled() || !mYAxis.isDrawLabelsEnabled()) - return; + if (!mYAxis.isEnabled() || !mYAxis.isDrawLabelsEnabled()) + return; - mAxisLabelPaint.setTypeface(mYAxis.getTypeface()); - mAxisLabelPaint.setTextSize(mYAxis.getTextSize()); - mAxisLabelPaint.setColor(mYAxis.getTextColor()); + mAxisLabelPaint.setTypeface(mYAxis.getTypeface()); + mAxisLabelPaint.setTextSize(mYAxis.getTextSize()); + mAxisLabelPaint.setColor(mYAxis.getTextColor()); - PointF center = mChart.getCenterOffsets(); - float factor = mChart.getFactor(); + PointF center = mChart.getCenterOffsets(); + float factor = mChart.getFactor(); - int labelCount = mYAxis.mEntryCount; + int labelCount = mYAxis.mEntryCount; - for (int j = 0; j < labelCount; j++) { + for (int j = 0; j < labelCount; j++) { - if (j == labelCount - 1 && mYAxis.isDrawTopYLabelEntryEnabled() == false) - break; + if (j == labelCount - 1 && mYAxis.isDrawTopYLabelEntryEnabled() == false) + break; - float r = (mYAxis.mEntries[j] - mYAxis.mAxisMinimum) * factor; + float r = (mYAxis.mEntries[j] - mYAxis.mAxisMinimum) * factor; - PointF p = Utils.getPosition(center, r, mChart.getRotationAngle()); + PointF p = Utils.getPosition(center, r, mChart.getRotationAngle()); - String label = mYAxis.getFormattedLabel(j); + String label = mYAxis.getFormattedLabel(j); - c.drawText(label, p.x + 10, p.y, mAxisLabelPaint); - } - } + c.drawText(label, p.x + 10, p.y, mAxisLabelPaint); + } + } - @Override - public void renderLimitLines(Canvas c) { + @Override + public void renderLimitLines(Canvas c) { - List limitLines = mYAxis.getLimitLines(); + List limitLines = mYAxis.getLimitLines(); - if (limitLines == null) - return; + if (limitLines == null) + return; - float sliceangle = mChart.getSliceAngle(); + float sliceangle = mChart.getSliceAngle(); - // calculate the factor that is needed for transforming the value to - // pixels - float factor = mChart.getFactor(); + // calculate the factor that is needed for transforming the value to + // pixels + float factor = mChart.getFactor(); - PointF center = mChart.getCenterOffsets(); + PointF center = mChart.getCenterOffsets(); - for (int i = 0; i < limitLines.size(); i++) { + for (int i = 0; i < limitLines.size(); i++) { - LimitLine l = limitLines.get(i); + LimitLine l = limitLines.get(i); - mLimitLinePaint.setColor(l.getLineColor()); - mLimitLinePaint.setPathEffect(l.getDashPathEffect()); - mLimitLinePaint.setStrokeWidth(l.getLineWidth()); + mLimitLinePaint.setColor(l.getLineColor()); + mLimitLinePaint.setPathEffect(l.getDashPathEffect()); + mLimitLinePaint.setStrokeWidth(l.getLineWidth()); - float r = (l.getLimit() - mChart.getYChartMin()) * factor; + float r = (l.getLimit() - mChart.getYChartMin()) * factor; - Path limitPath = new Path(); + Path limitPath = new Path(); - for (int j = 0; j < mChart.getData().getXValCount(); j++) { + for (int j = 0; j < mChart.getData().getXValCount(); j++) { - PointF p = Utils.getPosition(center, r, sliceangle * j + mChart.getRotationAngle()); + PointF p = Utils.getPosition(center, r, sliceangle * j + mChart.getRotationAngle()); - if (j == 0) - limitPath.moveTo(p.x, p.y); - else - limitPath.lineTo(p.x, p.y); - } + if (j == 0) + limitPath.moveTo(p.x, p.y); + else + limitPath.lineTo(p.x, p.y); + } - limitPath.close(); + limitPath.close(); - c.drawPath(limitPath, mLimitLinePaint); - } - } + c.drawPath(limitPath, mLimitLinePaint); + } + } }