1 package com.github.mikephil.charting.data; 2 3 import android.annotation.SuppressLint; 4 import android.graphics.drawable.Drawable; 5 6 import com.github.mikephil.charting.highlight.Range; 7 8 /** 9 * Entry class for the BarChart. (especially stacked bars) 10 * 11 * @author Philipp Jahoda 12 */ 13 @SuppressLint("ParcelCreator") 14 public class BarEntry extends Entry { 15 16 /** 17 * the values the stacked barchart holds 18 */ 19 private float[] mYVals; 20 21 /** 22 * the ranges for the individual stack values - automatically calculated 23 */ 24 private Range[] mRanges; 25 26 /** 27 * the sum of all negative values this entry (if stacked) contains 28 */ 29 private float mNegativeSum; 30 31 /** 32 * the sum of all positive values this entry (if stacked) contains 33 */ 34 private float mPositiveSum; 35 36 /** 37 * Constructor for normal bars (not stacked). 38 * 39 * @param x 40 * @param y 41 */ BarEntry(float x, float y)42 public BarEntry(float x, float y) { 43 super(x, y); 44 } 45 46 /** 47 * Constructor for normal bars (not stacked). 48 * 49 * @param x 50 * @param y 51 * @param data - Spot for additional data this Entry represents. 52 */ BarEntry(float x, float y, Object data)53 public BarEntry(float x, float y, Object data) { 54 super(x, y, data); 55 } 56 57 /** 58 * Constructor for normal bars (not stacked). 59 * 60 * @param x 61 * @param y 62 * @param icon - icon image 63 */ BarEntry(float x, float y, Drawable icon)64 public BarEntry(float x, float y, Drawable icon) { 65 super(x, y, icon); 66 } 67 68 /** 69 * Constructor for normal bars (not stacked). 70 * 71 * @param x 72 * @param y 73 * @param icon - icon image 74 * @param data - Spot for additional data this Entry represents. 75 */ BarEntry(float x, float y, Drawable icon, Object data)76 public BarEntry(float x, float y, Drawable icon, Object data) { 77 super(x, y, icon, data); 78 } 79 80 /** 81 * Constructor for stacked bar entries. One data object for whole stack 82 * 83 * @param x 84 * @param vals - the stack values, use at least 2 85 */ BarEntry(float x, float[] vals)86 public BarEntry(float x, float[] vals) { 87 super(x, calcSum(vals)); 88 89 this.mYVals = vals; 90 calcPosNegSum(); 91 calcRanges(); 92 } 93 94 /** 95 * Constructor for stacked bar entries. One data object for whole stack 96 * 97 * @param x 98 * @param vals - the stack values, use at least 2 99 * @param data - Spot for additional data this Entry represents. 100 */ BarEntry(float x, float[] vals, Object data)101 public BarEntry(float x, float[] vals, Object data) { 102 super(x, calcSum(vals), data); 103 104 this.mYVals = vals; 105 calcPosNegSum(); 106 calcRanges(); 107 } 108 109 /** 110 * Constructor for stacked bar entries. One data object for whole stack 111 * 112 * @param x 113 * @param vals - the stack values, use at least 2 114 * @param icon - icon image 115 */ BarEntry(float x, float[] vals, Drawable icon)116 public BarEntry(float x, float[] vals, Drawable icon) { 117 super(x, calcSum(vals), icon); 118 119 this.mYVals = vals; 120 calcPosNegSum(); 121 calcRanges(); 122 } 123 124 /** 125 * Constructor for stacked bar entries. One data object for whole stack 126 * 127 * @param x 128 * @param vals - the stack values, use at least 2 129 * @param icon - icon image 130 * @param data - Spot for additional data this Entry represents. 131 */ BarEntry(float x, float[] vals, Drawable icon, Object data)132 public BarEntry(float x, float[] vals, Drawable icon, Object data) { 133 super(x, calcSum(vals), icon, data); 134 135 this.mYVals = vals; 136 calcPosNegSum(); 137 calcRanges(); 138 } 139 140 /** 141 * Returns an exact copy of the BarEntry. 142 */ copy()143 public BarEntry copy() { 144 145 BarEntry copied = new BarEntry(getX(), getY(), getData()); 146 copied.setVals(mYVals); 147 return copied; 148 } 149 150 /** 151 * Returns the stacked values this BarEntry represents, or null, if only a single value is represented (then, use 152 * getY()). 153 * 154 * @return 155 */ getYVals()156 public float[] getYVals() { 157 return mYVals; 158 } 159 160 /** 161 * Set the array of values this BarEntry should represent. 162 * 163 * @param vals 164 */ setVals(float[] vals)165 public void setVals(float[] vals) { 166 setY(calcSum(vals)); 167 mYVals = vals; 168 calcPosNegSum(); 169 calcRanges(); 170 } 171 172 /** 173 * Returns the value of this BarEntry. If the entry is stacked, it returns the positive sum of all values. 174 * 175 * @return 176 */ 177 @Override getY()178 public float getY() { 179 return super.getY(); 180 } 181 182 /** 183 * Returns the ranges of the individual stack-entries. Will return null if this entry is not stacked. 184 * 185 * @return 186 */ getRanges()187 public Range[] getRanges() { 188 return mRanges; 189 } 190 191 /** 192 * Returns true if this BarEntry is stacked (has a values array), false if not. 193 * 194 * @return 195 */ isStacked()196 public boolean isStacked() { 197 return mYVals != null; 198 } 199 200 /** 201 * Use `getSumBelow(stackIndex)` instead. 202 */ 203 @Deprecated getBelowSum(int stackIndex)204 public float getBelowSum(int stackIndex) { 205 return getSumBelow(stackIndex); 206 } 207 getSumBelow(int stackIndex)208 public float getSumBelow(int stackIndex) { 209 210 if (mYVals == null) 211 return 0; 212 213 float remainder = 0f; 214 int index = mYVals.length - 1; 215 216 while (index > stackIndex && index >= 0) { 217 remainder += mYVals[index]; 218 index--; 219 } 220 221 return remainder; 222 } 223 224 /** 225 * Reuturns the sum of all positive values this entry (if stacked) contains. 226 * 227 * @return 228 */ getPositiveSum()229 public float getPositiveSum() { 230 return mPositiveSum; 231 } 232 233 /** 234 * Returns the sum of all negative values this entry (if stacked) contains. (this is a positive number) 235 * 236 * @return 237 */ getNegativeSum()238 public float getNegativeSum() { 239 return mNegativeSum; 240 } 241 calcPosNegSum()242 private void calcPosNegSum() { 243 244 if (mYVals == null) { 245 mNegativeSum = 0; 246 mPositiveSum = 0; 247 return; 248 } 249 250 float sumNeg = 0f; 251 float sumPos = 0f; 252 253 for (float f : mYVals) { 254 if (f <= 0f) 255 sumNeg += Math.abs(f); 256 else 257 sumPos += f; 258 } 259 260 mNegativeSum = sumNeg; 261 mPositiveSum = sumPos; 262 } 263 264 /** 265 * Calculates the sum across all values of the given stack. 266 * 267 * @param vals 268 * @return 269 */ calcSum(float[] vals)270 private static float calcSum(float[] vals) { 271 272 if (vals == null) 273 return 0f; 274 275 float sum = 0f; 276 277 for (float f : vals) 278 sum += f; 279 280 return sum; 281 } 282 calcRanges()283 protected void calcRanges() { 284 285 float[] values = getYVals(); 286 287 if (values == null || values.length == 0) 288 return; 289 290 mRanges = new Range[values.length]; 291 292 float negRemain = -getNegativeSum(); 293 float posRemain = 0f; 294 295 for (int i = 0; i < mRanges.length; i++) { 296 297 float value = values[i]; 298 299 if (value < 0) { 300 mRanges[i] = new Range(negRemain, negRemain - value); 301 negRemain -= value; 302 } else { 303 mRanges[i] = new Range(posRemain, posRemain + value); 304 posRemain += value; 305 } 306 } 307 } 308 } 309 310 311