1 package com.github.mikephil.charting.components; 2 3 import android.graphics.Color; 4 import android.graphics.Paint; 5 6 import com.github.mikephil.charting.utils.Utils; 7 8 /** 9 * Class representing the y-axis labels settings and its entries. Only use the setter methods to 10 * modify it. Do not 11 * access public variables directly. Be aware that not all features the YLabels class provides 12 * are suitable for the 13 * RadarChart. Customizations that affect the value range of the axis need to be applied before 14 * setting data for the 15 * chart. 16 * 17 * @author Philipp Jahoda 18 */ 19 public class YAxis extends AxisBase { 20 21 /** 22 * indicates if the bottom y-label entry is drawn or not 23 */ 24 private boolean mDrawBottomYLabelEntry = true; 25 26 /** 27 * indicates if the top y-label entry is drawn or not 28 */ 29 private boolean mDrawTopYLabelEntry = true; 30 31 /** 32 * flag that indicates if the axis is inverted or not 33 */ 34 protected boolean mInverted = false; 35 36 /** 37 * flag that indicates if the zero-line should be drawn regardless of other grid lines 38 */ 39 protected boolean mDrawZeroLine = false; 40 41 /** 42 * flag indicating that auto scale min restriction should be used 43 */ 44 private boolean mUseAutoScaleRestrictionMin = false; 45 46 /** 47 * flag indicating that auto scale max restriction should be used 48 */ 49 private boolean mUseAutoScaleRestrictionMax = false; 50 51 /** 52 * Color of the zero line 53 */ 54 protected int mZeroLineColor = Color.GRAY; 55 56 /** 57 * Width of the zero line in pixels 58 */ 59 protected float mZeroLineWidth = 1f; 60 61 /** 62 * axis space from the largest value to the top in percent of the total axis range 63 */ 64 protected float mSpacePercentTop = 10f; 65 66 /** 67 * axis space from the smallest value to the bottom in percent of the total axis range 68 */ 69 protected float mSpacePercentBottom = 10f; 70 71 /** 72 * the position of the y-labels relative to the chart 73 */ 74 private YAxisLabelPosition mPosition = YAxisLabelPosition.OUTSIDE_CHART; 75 76 /** 77 * the horizontal offset of the y-label 78 */ 79 private float mXLabelOffset = 0.0f; 80 81 /** 82 * enum for the position of the y-labels relative to the chart 83 */ 84 public enum YAxisLabelPosition { 85 OUTSIDE_CHART, INSIDE_CHART 86 } 87 88 /** 89 * the side this axis object represents 90 */ 91 private AxisDependency mAxisDependency; 92 93 /** 94 * the minimum width that the axis should take (in dp). 95 * <p/> 96 * default: 0.0 97 */ 98 protected float mMinWidth = 0.f; 99 100 /** 101 * the maximum width that the axis can take (in dp). 102 * use Inifinity for disabling the maximum 103 * default: Float.POSITIVE_INFINITY (no maximum specified) 104 */ 105 protected float mMaxWidth = Float.POSITIVE_INFINITY; 106 107 /** 108 * Enum that specifies the axis a DataSet should be plotted against, either LEFT or RIGHT. 109 * 110 * @author Philipp Jahoda 111 */ 112 public enum AxisDependency { 113 LEFT, RIGHT 114 } 115 YAxis()116 public YAxis() { 117 super(); 118 119 // default left 120 this.mAxisDependency = AxisDependency.LEFT; 121 this.mYOffset = 0f; 122 } 123 YAxis(AxisDependency position)124 public YAxis(AxisDependency position) { 125 super(); 126 this.mAxisDependency = position; 127 this.mYOffset = 0f; 128 } 129 getAxisDependency()130 public AxisDependency getAxisDependency() { 131 return mAxisDependency; 132 } 133 134 /** 135 * @return the minimum width that the axis should take (in dp). 136 */ getMinWidth()137 public float getMinWidth() { 138 return mMinWidth; 139 } 140 141 /** 142 * Sets the minimum width that the axis should take (in dp). 143 * 144 * @param minWidth 145 */ setMinWidth(float minWidth)146 public void setMinWidth(float minWidth) { 147 mMinWidth = minWidth; 148 } 149 150 /** 151 * @return the maximum width that the axis can take (in dp). 152 */ getMaxWidth()153 public float getMaxWidth() { 154 return mMaxWidth; 155 } 156 157 /** 158 * Sets the maximum width that the axis can take (in dp). 159 * 160 * @param maxWidth 161 */ setMaxWidth(float maxWidth)162 public void setMaxWidth(float maxWidth) { 163 mMaxWidth = maxWidth; 164 } 165 166 /** 167 * returns the position of the y-labels 168 */ getLabelPosition()169 public YAxisLabelPosition getLabelPosition() { 170 return mPosition; 171 } 172 173 /** 174 * sets the position of the y-labels 175 * 176 * @param pos 177 */ setPosition(YAxisLabelPosition pos)178 public void setPosition(YAxisLabelPosition pos) { 179 mPosition = pos; 180 } 181 182 /** 183 * returns the horizontal offset of the y-label 184 */ getLabelXOffset()185 public float getLabelXOffset() { 186 return mXLabelOffset; 187 } 188 189 /** 190 * sets the horizontal offset of the y-label 191 * 192 * @param xOffset 193 */ setLabelXOffset(float xOffset)194 public void setLabelXOffset(float xOffset) { 195 mXLabelOffset = xOffset; 196 } 197 198 /** 199 * returns true if drawing the top y-axis label entry is enabled 200 * 201 * @return 202 */ isDrawTopYLabelEntryEnabled()203 public boolean isDrawTopYLabelEntryEnabled() { 204 return mDrawTopYLabelEntry; 205 } 206 207 /** 208 * returns true if drawing the bottom y-axis label entry is enabled 209 * 210 * @return 211 */ isDrawBottomYLabelEntryEnabled()212 public boolean isDrawBottomYLabelEntryEnabled() { 213 return mDrawBottomYLabelEntry; 214 } 215 216 /** 217 * set this to true to enable drawing the top y-label entry. Disabling this can be helpful 218 * when the top y-label and 219 * left x-label interfere with each other. default: true 220 * 221 * @param enabled 222 */ setDrawTopYLabelEntry(boolean enabled)223 public void setDrawTopYLabelEntry(boolean enabled) { 224 mDrawTopYLabelEntry = enabled; 225 } 226 227 /** 228 * If this is set to true, the y-axis is inverted which means that low values are on top of 229 * the chart, high values 230 * on bottom. 231 * 232 * @param enabled 233 */ setInverted(boolean enabled)234 public void setInverted(boolean enabled) { 235 mInverted = enabled; 236 } 237 238 /** 239 * If this returns true, the y-axis is inverted. 240 * 241 * @return 242 */ isInverted()243 public boolean isInverted() { 244 return mInverted; 245 } 246 247 /** 248 * This method is deprecated. 249 * Use setAxisMinimum(...) / setAxisMaximum(...) instead. 250 * 251 * @param startAtZero 252 */ 253 @Deprecated setStartAtZero(boolean startAtZero)254 public void setStartAtZero(boolean startAtZero) { 255 if (startAtZero) 256 setAxisMinimum(0f); 257 else 258 resetAxisMinimum(); 259 } 260 261 /** 262 * Sets the top axis space in percent of the full range. Default 10f 263 * 264 * @param percent 265 */ setSpaceTop(float percent)266 public void setSpaceTop(float percent) { 267 mSpacePercentTop = percent; 268 } 269 270 /** 271 * Returns the top axis space in percent of the full range. Default 10f 272 * 273 * @return 274 */ getSpaceTop()275 public float getSpaceTop() { 276 return mSpacePercentTop; 277 } 278 279 /** 280 * Sets the bottom axis space in percent of the full range. Default 10f 281 * 282 * @param percent 283 */ setSpaceBottom(float percent)284 public void setSpaceBottom(float percent) { 285 mSpacePercentBottom = percent; 286 } 287 288 /** 289 * Returns the bottom axis space in percent of the full range. Default 10f 290 * 291 * @return 292 */ getSpaceBottom()293 public float getSpaceBottom() { 294 return mSpacePercentBottom; 295 } 296 isDrawZeroLineEnabled()297 public boolean isDrawZeroLineEnabled() { 298 return mDrawZeroLine; 299 } 300 301 /** 302 * Set this to true to draw the zero-line regardless of weather other 303 * grid-lines are enabled or not. Default: false 304 * 305 * @param mDrawZeroLine 306 */ setDrawZeroLine(boolean mDrawZeroLine)307 public void setDrawZeroLine(boolean mDrawZeroLine) { 308 this.mDrawZeroLine = mDrawZeroLine; 309 } 310 getZeroLineColor()311 public int getZeroLineColor() { 312 return mZeroLineColor; 313 } 314 315 /** 316 * Sets the color of the zero line 317 * 318 * @param color 319 */ setZeroLineColor(int color)320 public void setZeroLineColor(int color) { 321 mZeroLineColor = color; 322 } 323 getZeroLineWidth()324 public float getZeroLineWidth() { 325 return mZeroLineWidth; 326 } 327 328 /** 329 * Sets the width of the zero line in dp 330 * 331 * @param width 332 */ setZeroLineWidth(float width)333 public void setZeroLineWidth(float width) { 334 this.mZeroLineWidth = Utils.convertDpToPixel(width); 335 } 336 337 /** 338 * This is for normal (not horizontal) charts horizontal spacing. 339 * 340 * @param p 341 * @return 342 */ getRequiredWidthSpace(Paint p)343 public float getRequiredWidthSpace(Paint p) { 344 345 p.setTextSize(mTextSize); 346 347 String label = getLongestLabel(); 348 float width = (float) Utils.calcTextWidth(p, label) + getXOffset() * 2f; 349 350 float minWidth = getMinWidth(); 351 float maxWidth = getMaxWidth(); 352 353 if (minWidth > 0.f) 354 minWidth = Utils.convertDpToPixel(minWidth); 355 356 if (maxWidth > 0.f && maxWidth != Float.POSITIVE_INFINITY) 357 maxWidth = Utils.convertDpToPixel(maxWidth); 358 359 width = Math.max(minWidth, Math.min(width, maxWidth > 0.0 ? maxWidth : width)); 360 361 return width; 362 } 363 364 /** 365 * This is for HorizontalBarChart vertical spacing. 366 * 367 * @param p 368 * @return 369 */ getRequiredHeightSpace(Paint p)370 public float getRequiredHeightSpace(Paint p) { 371 372 p.setTextSize(mTextSize); 373 374 String label = getLongestLabel(); 375 return (float) Utils.calcTextHeight(p, label) + getYOffset() * 2f; 376 } 377 378 /** 379 * Returns true if this axis needs horizontal offset, false if no offset is needed. 380 * 381 * @return 382 */ needsOffset()383 public boolean needsOffset() { 384 if (isEnabled() && isDrawLabelsEnabled() && getLabelPosition() == YAxisLabelPosition 385 .OUTSIDE_CHART) 386 return true; 387 else 388 return false; 389 } 390 391 /** 392 * Returns true if autoscale restriction for axis min value is enabled 393 */ 394 @Deprecated isUseAutoScaleMinRestriction( )395 public boolean isUseAutoScaleMinRestriction( ) { 396 return mUseAutoScaleRestrictionMin; 397 } 398 399 /** 400 * Sets autoscale restriction for axis min value as enabled/disabled 401 */ 402 @Deprecated setUseAutoScaleMinRestriction( boolean isEnabled )403 public void setUseAutoScaleMinRestriction( boolean isEnabled ) { 404 mUseAutoScaleRestrictionMin = isEnabled; 405 } 406 407 /** 408 * Returns true if autoscale restriction for axis max value is enabled 409 */ 410 @Deprecated isUseAutoScaleMaxRestriction()411 public boolean isUseAutoScaleMaxRestriction() { 412 return mUseAutoScaleRestrictionMax; 413 } 414 415 /** 416 * Sets autoscale restriction for axis max value as enabled/disabled 417 */ 418 @Deprecated setUseAutoScaleMaxRestriction( boolean isEnabled )419 public void setUseAutoScaleMaxRestriction( boolean isEnabled ) { 420 mUseAutoScaleRestrictionMax = isEnabled; 421 } 422 423 424 @Override calculate(float dataMin, float dataMax)425 public void calculate(float dataMin, float dataMax) { 426 427 float min = dataMin; 428 float max = dataMax; 429 430 // Make sure max is greater than min 431 // Discussion: https://github.com/danielgindi/Charts/pull/3650#discussion_r221409991 432 if (min > max) 433 { 434 if (mCustomAxisMax && mCustomAxisMin) 435 { 436 float t = min; 437 min = max; 438 max = t; 439 } 440 else if (mCustomAxisMax) 441 { 442 min = max < 0f ? max * 1.5f : max * 0.5f; 443 } 444 else if (mCustomAxisMin) 445 { 446 max = min < 0f ? min * 0.5f : min * 1.5f; 447 } 448 } 449 450 float range = Math.abs(max - min); 451 452 // in case all values are equal 453 if (range == 0f) { 454 max = max + 1f; 455 min = min - 1f; 456 } 457 458 // recalculate 459 range = Math.abs(max - min); 460 461 // calc extra spacing 462 this.mAxisMinimum = mCustomAxisMin ? this.mAxisMinimum : min - (range / 100f) * getSpaceBottom(); 463 this.mAxisMaximum = mCustomAxisMax ? this.mAxisMaximum : max + (range / 100f) * getSpaceTop(); 464 465 this.mAxisRange = Math.abs(this.mAxisMinimum - this.mAxisMaximum); 466 } 467 } 468