package com.github.mikephil.charting.components;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.util.Log;
import com.github.mikephil.charting.formatter.DefaultAxisValueFormatter;
import com.github.mikephil.charting.formatter.IAxisValueFormatter;
import com.github.mikephil.charting.utils.Utils;
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<LimitLine> mLimitLines;
/**
* flag indicating the limit lines layer depth
*/
protected boolean mDrawLimitLineBehindData = false;
/**
* 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;
/**
* default constructor
*/
public AxisBase() {
this.mTextSize = Utils.convertDpToPixel(10f);
this.mXOffset = Utils.convertDpToPixel(5f);
this.mYOffset = Utils.convertDpToPixel(5f);
this.mLimitLines = new ArrayList<LimitLine>();
}
/**
* Set this to true to enable drawing the grid lines for this axis.
*
* @param enabled
*/
public void setDrawGridLines(boolean enabled) {
mDrawGridLines = enabled;
}
/**
* Returns true if drawing grid lines is enabled for this axis.
*
* @return
*/
public boolean isDrawGridLinesEnabled() {
return mDrawGridLines;
}
/**
* Set this to true if the line alongside the axis should be drawn or not.
*
* @param enabled
*/
public void setDrawAxisLine(boolean enabled) {
mDrawAxisLine = enabled;
}
/**
* Returns true if the line alongside the axis should be drawn.
*
* @return
*/
public boolean isDrawAxisLineEnabled() {
return mDrawAxisLine;
}
/**
* Centers the axis labels instead of drawing them at their original position.
* This is useful especially for grouped BarChart.
*
* @param enabled
*/
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).
*
* @param color
*/
public void setGridColor(int color) {
mGridColor = color;
}
/**
* Returns the color of the grid lines for this axis (the horizontal lines
* coming from each label).
*
* @return
*/
public int getGridColor() {
return mGridColor;
}
/**
* Sets the width of the border surrounding the chart in dp.
*
* @param width
*/
public void setAxisLineWidth(float width) {
mAxisLineWidth = Utils.convertDpToPixel(width);
}
/**
* Returns the width of the axis line (line alongside the axis).
*
* @return
*/
public float getAxisLineWidth() {
return mAxisLineWidth;
}
/**
* Sets the width of the grid lines that are drawn away from each axis
* label.
*
* @param width
*/
public void setGridLineWidth(float width) {
mGridLineWidth = Utils.convertDpToPixel(width);
}
/**
* Returns the width of the grid lines that are drawn away from each axis
* label.
*
* @return
*/
public float getGridLineWidth() {
return mGridLineWidth;
}
/**
* Sets the color of the border surrounding the chart.
*
* @param color
*/
public void setAxisLineColor(int color) {
mAxisLineColor = color;
}
/**
* Returns the color of the axis line (line alongside the axis).
*
* @return
*/
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).
*
* @param enabled
*/
public void setDrawLabels(boolean enabled) {
mDrawLabels = enabled;
}
/**
* Returns true if drawing the labels is enabled for this axis.
*
* @return
*/
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 > 25)
count = 25;
if (count < 2)
count = 2;
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
*
* @return
*/
public boolean isForceLabelsEnabled() {
return mForceLabels;
}
/**
* Returns the number of label entries the y-axis should have
*
* @return
*/
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
*
* @param enabled
*/
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.
*
* @param granularity
*/
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.
*
* @param l
*/
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?");
}
}
/**
* Removes the specified LimitLine from the axis.
*
* @param l
*/
public void removeLimitLine(LimitLine l) {
mLimitLines.remove(l);
}
/**
* Removes all LimitLines from the axis.
*/
public void removeAllLimitLines() {
mLimitLines.clear();
}
/**
* Returns the LimitLines of this axis.
*
* @return
*/
public List<LimitLine> getLimitLines() {
return mLimitLines;
}
/**
* If this is set to true, the LimitLines are drawn behind the actual data,
* otherwise on top. Default: false
*
* @param enabled
*/
public void setDrawLimitLinesBehindData(boolean enabled) {
mDrawLimitLineBehindData = enabled;
}
public boolean isDrawLimitLinesBehindDataEnabled() {
return mDrawLimitLineBehindData;
}
/**
* Returns the longest formatted label (in terms of characters), this axis
* contains.
*
* @return
*/
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;
}
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.
*
* @param f
*/
public void setValueFormatter(IAxisValueFormatter f) {
if (f == null)
mAxisValueFormatter = new DefaultAxisValueFormatter(mDecimals);
else
mAxisValueFormatter = f;
}
/**
* Returns the formatter used for formatting the axis labels.
*
* @return
*/
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.
*
* @return
*/
public boolean isGridDashedLineEnabled() {
return mGridDashPathEffect == null ? false : true;
}
/**
* returns the DashPathEffect that is set for grid line
*
* @return
*/
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.
*
* @return
*/
public boolean isAxisLineDashedLineEnabled() {
return mAxisLineDashPathEffect == null ? false : true;
}
/**
* returns the DashPathEffect that is set for axis line
*
* @return
*/
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)
*
* @return
*/
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)
*
* @return
*/
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.
*
* @param min
*/
public void setAxisMinimum(float min) {
mCustomAxisMin = true;
mAxisMinimum = min;
this.mAxisRange = Math.abs(mAxisMaximum - min);
}
/**
* Use setAxisMinimum(...) instead.
*
* @param min
*/
@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.
*
* @param max
*/
public void setAxisMaximum(float max) {
mCustomAxisMax = true;
mAxisMaximum = max;
this.mAxisRange = Math.abs(max - mAxisMinimum);
}
/**
* Use setAxisMaximum(...) instead.
*
* @param max
*/
@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;
}
}