• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 
2 package com.github.mikephil.charting.components;
3 
4 import android.graphics.Color;
5 import android.graphics.DashPathEffect;
6 import android.util.Log;
7 
8 import com.github.mikephil.charting.formatter.DefaultAxisValueFormatter;
9 import com.github.mikephil.charting.formatter.IAxisValueFormatter;
10 import com.github.mikephil.charting.utils.Utils;
11 
12 import java.util.ArrayList;
13 import java.util.List;
14 
15 /**
16  * Base-class of all axes (previously called labels).
17  *
18  * @author Philipp Jahoda
19  */
20 public abstract class AxisBase extends ComponentBase {
21 
22     /**
23      * custom formatter that is used instead of the auto-formatter if set
24      */
25     protected IAxisValueFormatter mAxisValueFormatter;
26 
27     private int mGridColor = Color.GRAY;
28 
29     private float mGridLineWidth = 1f;
30 
31     private int mAxisLineColor = Color.GRAY;
32 
33     private float mAxisLineWidth = 1f;
34 
35     /**
36      * the actual array of entries
37      */
38     public float[] mEntries = new float[]{};
39 
40     /**
41      * axis label entries only used for centered labels
42      */
43     public float[] mCenteredEntries = new float[]{};
44 
45     /**
46      * the number of entries the legend contains
47      */
48     public int mEntryCount;
49 
50     /**
51      * the number of decimal digits to use
52      */
53     public int mDecimals;
54 
55     /**
56      * the number of label entries the axis should have, default 6
57      */
58     private int mLabelCount = 6;
59 
60     /**
61      * the minimum interval between axis values
62      */
63     protected float mGranularity = 1.0f;
64 
65     /**
66      * When true, axis labels are controlled by the `granularity` property.
67      * When false, axis values could possibly be repeated.
68      * This could happen if two adjacent axis values are rounded to same value.
69      * If using granularity this could be avoided by having fewer axis values visible.
70      */
71     protected boolean mGranularityEnabled = false;
72 
73     /**
74      * if true, the set number of y-labels will be forced
75      */
76     protected boolean mForceLabels = false;
77 
78     /**
79      * flag indicating if the grid lines for this axis should be drawn
80      */
81     protected boolean mDrawGridLines = true;
82 
83     /**
84      * flag that indicates if the line alongside the axis is drawn or not
85      */
86     protected boolean mDrawAxisLine = true;
87 
88     /**
89      * flag that indicates of the labels of this axis should be drawn or not
90      */
91     protected boolean mDrawLabels = true;
92 
93     protected boolean mCenterAxisLabels = false;
94 
95     /**
96      * the path effect of the axis line that makes dashed lines possible
97      */
98     private DashPathEffect mAxisLineDashPathEffect = null;
99 
100     /**
101      * the path effect of the grid lines that makes dashed lines possible
102      */
103     private DashPathEffect mGridDashPathEffect = null;
104 
105     /**
106      * array of limit lines that can be set for the axis
107      */
108     protected List<LimitLine> mLimitLines;
109 
110     /**
111      * flag indicating the limit lines layer depth
112      */
113     protected boolean mDrawLimitLineBehindData = false;
114 
115     /**
116      * flag indicating the grid lines layer depth
117      */
118     protected boolean mDrawGridLinesBehindData = true;
119 
120     /**
121      * Extra spacing for `axisMinimum` to be added to automatically calculated `axisMinimum`
122      */
123     protected float mSpaceMin = 0.f;
124 
125     /**
126      * Extra spacing for `axisMaximum` to be added to automatically calculated `axisMaximum`
127      */
128     protected float mSpaceMax = 0.f;
129 
130     /**
131      * flag indicating that the axis-min value has been customized
132      */
133     protected boolean mCustomAxisMin = false;
134 
135     /**
136      * flag indicating that the axis-max value has been customized
137      */
138     protected boolean mCustomAxisMax = false;
139 
140     /**
141      * don't touch this direclty, use setter
142      */
143     public float mAxisMaximum = 0f;
144 
145     /**
146      * don't touch this directly, use setter
147      */
148     public float mAxisMinimum = 0f;
149 
150     /**
151      * the total range of values this axis covers
152      */
153     public float mAxisRange = 0f;
154 
155     private int mAxisMinLabels = 2;
156     private int mAxisMaxLabels = 25;
157 
158     /**
159      * The minumum number of labels on the axis
160      */
getAxisMinLabels()161     public int getAxisMinLabels() {
162         return mAxisMinLabels;
163     }
164 
165     /**
166      * The minumum number of labels on the axis
167      */
setAxisMinLabels(int labels)168     public void setAxisMinLabels(int labels) {
169         if (labels > 0)
170             mAxisMinLabels = labels;
171     }
172 
173     /**
174      * The maximum number of labels on the axis
175      */
getAxisMaxLabels()176     public int getAxisMaxLabels() {
177         return mAxisMaxLabels;
178     }
179 
180     /**
181      * The maximum number of labels on the axis
182      */
setAxisMaxLabels(int labels)183     public void setAxisMaxLabels(int labels) {
184         if (labels > 0)
185             mAxisMaxLabels = labels;
186     }
187 
188     /**
189      * default constructor
190      */
AxisBase()191     public AxisBase() {
192         this.mTextSize = Utils.convertDpToPixel(10f);
193         this.mXOffset = Utils.convertDpToPixel(5f);
194         this.mYOffset = Utils.convertDpToPixel(5f);
195         this.mLimitLines = new ArrayList<LimitLine>();
196     }
197 
198     /**
199      * Set this to true to enable drawing the grid lines for this axis.
200      *
201      * @param enabled
202      */
setDrawGridLines(boolean enabled)203     public void setDrawGridLines(boolean enabled) {
204         mDrawGridLines = enabled;
205     }
206 
207     /**
208      * Returns true if drawing grid lines is enabled for this axis.
209      *
210      * @return
211      */
isDrawGridLinesEnabled()212     public boolean isDrawGridLinesEnabled() {
213         return mDrawGridLines;
214     }
215 
216     /**
217      * Set this to true if the line alongside the axis should be drawn or not.
218      *
219      * @param enabled
220      */
setDrawAxisLine(boolean enabled)221     public void setDrawAxisLine(boolean enabled) {
222         mDrawAxisLine = enabled;
223     }
224 
225     /**
226      * Returns true if the line alongside the axis should be drawn.
227      *
228      * @return
229      */
isDrawAxisLineEnabled()230     public boolean isDrawAxisLineEnabled() {
231         return mDrawAxisLine;
232     }
233 
234     /**
235      * Centers the axis labels instead of drawing them at their original position.
236      * This is useful especially for grouped BarChart.
237      *
238      * @param enabled
239      */
setCenterAxisLabels(boolean enabled)240     public void setCenterAxisLabels(boolean enabled) {
241         mCenterAxisLabels = enabled;
242     }
243 
isCenterAxisLabelsEnabled()244     public boolean isCenterAxisLabelsEnabled() {
245         return mCenterAxisLabels && mEntryCount > 0;
246     }
247 
248     /**
249      * Sets the color of the grid lines for this axis (the horizontal lines
250      * coming from each label).
251      *
252      * @param color
253      */
setGridColor(int color)254     public void setGridColor(int color) {
255         mGridColor = color;
256     }
257 
258     /**
259      * Returns the color of the grid lines for this axis (the horizontal lines
260      * coming from each label).
261      *
262      * @return
263      */
getGridColor()264     public int getGridColor() {
265         return mGridColor;
266     }
267 
268     /**
269      * Sets the width of the border surrounding the chart in dp.
270      *
271      * @param width
272      */
setAxisLineWidth(float width)273     public void setAxisLineWidth(float width) {
274         mAxisLineWidth = Utils.convertDpToPixel(width);
275     }
276 
277     /**
278      * Returns the width of the axis line (line alongside the axis).
279      *
280      * @return
281      */
getAxisLineWidth()282     public float getAxisLineWidth() {
283         return mAxisLineWidth;
284     }
285 
286     /**
287      * Sets the width of the grid lines that are drawn away from each axis
288      * label.
289      *
290      * @param width
291      */
setGridLineWidth(float width)292     public void setGridLineWidth(float width) {
293         mGridLineWidth = Utils.convertDpToPixel(width);
294     }
295 
296     /**
297      * Returns the width of the grid lines that are drawn away from each axis
298      * label.
299      *
300      * @return
301      */
getGridLineWidth()302     public float getGridLineWidth() {
303         return mGridLineWidth;
304     }
305 
306     /**
307      * Sets the color of the border surrounding the chart.
308      *
309      * @param color
310      */
setAxisLineColor(int color)311     public void setAxisLineColor(int color) {
312         mAxisLineColor = color;
313     }
314 
315     /**
316      * Returns the color of the axis line (line alongside the axis).
317      *
318      * @return
319      */
getAxisLineColor()320     public int getAxisLineColor() {
321         return mAxisLineColor;
322     }
323 
324     /**
325      * Set this to true to enable drawing the labels of this axis (this will not
326      * affect drawing the grid lines or axis lines).
327      *
328      * @param enabled
329      */
setDrawLabels(boolean enabled)330     public void setDrawLabels(boolean enabled) {
331         mDrawLabels = enabled;
332     }
333 
334     /**
335      * Returns true if drawing the labels is enabled for this axis.
336      *
337      * @return
338      */
isDrawLabelsEnabled()339     public boolean isDrawLabelsEnabled() {
340         return mDrawLabels;
341     }
342 
343     /**
344      * Sets the number of label entries for the y-axis max = 25, min = 2, default: 6, be aware
345      * that this number is not fixed.
346      *
347      * @param count the number of y-axis labels that should be displayed
348      */
setLabelCount(int count)349     public void setLabelCount(int count) {
350 
351         if (count > getAxisMaxLabels())
352             count = getAxisMaxLabels();
353         if (count < getAxisMinLabels())
354             count = getAxisMinLabels();
355 
356         mLabelCount = count;
357         mForceLabels = false;
358     }
359 
360     /**
361      * sets the number of label entries for the y-axis max = 25, min = 2, default: 6, be aware
362      * that this number is not
363      * fixed (if force == false) and can only be approximated.
364      *
365      * @param count the number of y-axis labels that should be displayed
366      * @param force if enabled, the set label count will be forced, meaning that the exact
367      *              specified count of labels will
368      *              be drawn and evenly distributed alongside the axis - this might cause labels
369      *              to have uneven values
370      */
setLabelCount(int count, boolean force)371     public void setLabelCount(int count, boolean force) {
372 
373         setLabelCount(count);
374         mForceLabels = force;
375     }
376 
377     /**
378      * Returns true if focing the y-label count is enabled. Default: false
379      *
380      * @return
381      */
isForceLabelsEnabled()382     public boolean isForceLabelsEnabled() {
383         return mForceLabels;
384     }
385 
386     /**
387      * Returns the number of label entries the y-axis should have
388      *
389      * @return
390      */
getLabelCount()391     public int getLabelCount() {
392         return mLabelCount;
393     }
394 
395     /**
396      * @return true if granularity is enabled
397      */
isGranularityEnabled()398     public boolean isGranularityEnabled() {
399         return mGranularityEnabled;
400     }
401 
402     /**
403      * Enabled/disable granularity control on axis value intervals. If enabled, the axis
404      * interval is not allowed to go below a certain granularity. Default: false
405      *
406      * @param enabled
407      */
setGranularityEnabled(boolean enabled)408     public void setGranularityEnabled(boolean enabled) {
409         mGranularityEnabled = enabled;
410     }
411 
412     /**
413      * @return the minimum interval between axis values
414      */
getGranularity()415     public float getGranularity() {
416         return mGranularity;
417     }
418 
419     /**
420      * Set a minimum interval for the axis when zooming in. The axis is not allowed to go below
421      * that limit. This can be used to avoid label duplicating when zooming in.
422      *
423      * @param granularity
424      */
setGranularity(float granularity)425     public void setGranularity(float granularity) {
426         mGranularity = granularity;
427         // set this to true if it was disabled, as it makes no sense to call this method with granularity disabled
428         mGranularityEnabled = true;
429     }
430 
431     /**
432      * Adds a new LimitLine to this axis.
433      *
434      * @param l
435      */
addLimitLine(LimitLine l)436     public void addLimitLine(LimitLine l) {
437         mLimitLines.add(l);
438 
439         if (mLimitLines.size() > 6) {
440             Log.e("MPAndroiChart",
441                     "Warning! You have more than 6 LimitLines on your axis, do you really want " +
442                             "that?");
443         }
444     }
445 
446     /**
447      * Removes the specified LimitLine from the axis.
448      *
449      * @param l
450      */
removeLimitLine(LimitLine l)451     public void removeLimitLine(LimitLine l) {
452         mLimitLines.remove(l);
453     }
454 
455     /**
456      * Removes all LimitLines from the axis.
457      */
removeAllLimitLines()458     public void removeAllLimitLines() {
459         mLimitLines.clear();
460     }
461 
462     /**
463      * Returns the LimitLines of this axis.
464      *
465      * @return
466      */
getLimitLines()467     public List<LimitLine> getLimitLines() {
468         return mLimitLines;
469     }
470 
471     /**
472      * If this is set to true, the LimitLines are drawn behind the actual data,
473      * otherwise on top. Default: false
474      *
475      * @param enabled
476      */
setDrawLimitLinesBehindData(boolean enabled)477     public void setDrawLimitLinesBehindData(boolean enabled) {
478         mDrawLimitLineBehindData = enabled;
479     }
480 
isDrawLimitLinesBehindDataEnabled()481     public boolean isDrawLimitLinesBehindDataEnabled() {
482         return mDrawLimitLineBehindData;
483     }
484 
485     /**
486      * If this is set to false, the grid lines are draw on top of the actual data,
487      * otherwise behind. Default: true
488      *
489      * @param enabled
490      */
setDrawGridLinesBehindData(boolean enabled)491     public void setDrawGridLinesBehindData(boolean enabled) { mDrawGridLinesBehindData = enabled; }
492 
isDrawGridLinesBehindDataEnabled()493     public boolean isDrawGridLinesBehindDataEnabled() {
494         return mDrawGridLinesBehindData;
495     }
496 
497     /**
498      * Returns the longest formatted label (in terms of characters), this axis
499      * contains.
500      *
501      * @return
502      */
getLongestLabel()503     public String getLongestLabel() {
504 
505         String longest = "";
506 
507         for (int i = 0; i < mEntries.length; i++) {
508             String text = getFormattedLabel(i);
509 
510             if (text != null && longest.length() < text.length())
511                 longest = text;
512         }
513 
514         return longest;
515     }
516 
getFormattedLabel(int index)517     public String getFormattedLabel(int index) {
518 
519         if (index < 0 || index >= mEntries.length)
520             return "";
521         else
522             return getValueFormatter().getFormattedValue(mEntries[index], this);
523     }
524 
525     /**
526      * Sets the formatter to be used for formatting the axis labels. If no formatter is set, the
527      * chart will
528      * automatically determine a reasonable formatting (concerning decimals) for all the values
529      * that are drawn inside
530      * the chart. Use chart.getDefaultValueFormatter() to use the formatter calculated by the chart.
531      *
532      * @param f
533      */
setValueFormatter(IAxisValueFormatter f)534     public void setValueFormatter(IAxisValueFormatter f) {
535 
536         if (f == null)
537             mAxisValueFormatter = new DefaultAxisValueFormatter(mDecimals);
538         else
539             mAxisValueFormatter = f;
540     }
541 
542     /**
543      * Returns the formatter used for formatting the axis labels.
544      *
545      * @return
546      */
getValueFormatter()547     public IAxisValueFormatter getValueFormatter() {
548 
549         if (mAxisValueFormatter == null ||
550                 (mAxisValueFormatter instanceof DefaultAxisValueFormatter &&
551                         ((DefaultAxisValueFormatter)mAxisValueFormatter).getDecimalDigits() != mDecimals))
552             mAxisValueFormatter = new DefaultAxisValueFormatter(mDecimals);
553 
554         return mAxisValueFormatter;
555     }
556 
557     /**
558      * Enables the grid line to be drawn in dashed mode, e.g. like this
559      * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF.
560      * Keep in mind that hardware acceleration boosts performance.
561      *
562      * @param lineLength  the length of the line pieces
563      * @param spaceLength the length of space in between the pieces
564      * @param phase       offset, in degrees (normally, use 0)
565      */
enableGridDashedLine(float lineLength, float spaceLength, float phase)566     public void enableGridDashedLine(float lineLength, float spaceLength, float phase) {
567         mGridDashPathEffect = new DashPathEffect(new float[]{
568                 lineLength, spaceLength
569         }, phase);
570     }
571 
572     /**
573      * Enables the grid line to be drawn in dashed mode, e.g. like this
574      * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF.
575      * Keep in mind that hardware acceleration boosts performance.
576      *
577      * @param effect the DashPathEffect
578      */
setGridDashedLine(DashPathEffect effect)579     public void setGridDashedLine(DashPathEffect effect) {
580         mGridDashPathEffect = effect;
581     }
582 
583     /**
584      * Disables the grid line to be drawn in dashed mode.
585      */
disableGridDashedLine()586     public void disableGridDashedLine() {
587         mGridDashPathEffect = null;
588     }
589 
590     /**
591      * Returns true if the grid dashed-line effect is enabled, false if not.
592      *
593      * @return
594      */
isGridDashedLineEnabled()595     public boolean isGridDashedLineEnabled() {
596         return mGridDashPathEffect == null ? false : true;
597     }
598 
599     /**
600      * returns the DashPathEffect that is set for grid line
601      *
602      * @return
603      */
getGridDashPathEffect()604     public DashPathEffect getGridDashPathEffect() {
605         return mGridDashPathEffect;
606     }
607 
608 
609     /**
610      * Enables the axis line to be drawn in dashed mode, e.g. like this
611      * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF.
612      * Keep in mind that hardware acceleration boosts performance.
613      *
614      * @param lineLength  the length of the line pieces
615      * @param spaceLength the length of space in between the pieces
616      * @param phase       offset, in degrees (normally, use 0)
617      */
enableAxisLineDashedLine(float lineLength, float spaceLength, float phase)618     public void enableAxisLineDashedLine(float lineLength, float spaceLength, float phase) {
619         mAxisLineDashPathEffect = new DashPathEffect(new float[]{
620                 lineLength, spaceLength
621         }, phase);
622     }
623 
624     /**
625      * Enables the axis line to be drawn in dashed mode, e.g. like this
626      * "- - - - - -". THIS ONLY WORKS IF HARDWARE-ACCELERATION IS TURNED OFF.
627      * Keep in mind that hardware acceleration boosts performance.
628      *
629      * @param effect the DashPathEffect
630      */
setAxisLineDashedLine(DashPathEffect effect)631     public void setAxisLineDashedLine(DashPathEffect effect) {
632         mAxisLineDashPathEffect = effect;
633     }
634 
635     /**
636      * Disables the axis line to be drawn in dashed mode.
637      */
disableAxisLineDashedLine()638     public void disableAxisLineDashedLine() {
639         mAxisLineDashPathEffect = null;
640     }
641 
642     /**
643      * Returns true if the axis dashed-line effect is enabled, false if not.
644      *
645      * @return
646      */
isAxisLineDashedLineEnabled()647     public boolean isAxisLineDashedLineEnabled() {
648         return mAxisLineDashPathEffect == null ? false : true;
649     }
650 
651     /**
652      * returns the DashPathEffect that is set for axis line
653      *
654      * @return
655      */
getAxisLineDashPathEffect()656     public DashPathEffect getAxisLineDashPathEffect() {
657         return mAxisLineDashPathEffect;
658     }
659 
660     /**
661      * ###### BELOW CODE RELATED TO CUSTOM AXIS VALUES ######
662      */
663 
getAxisMaximum()664     public float getAxisMaximum() {
665         return mAxisMaximum;
666     }
667 
getAxisMinimum()668     public float getAxisMinimum() {
669         return mAxisMinimum;
670     }
671 
672     /**
673      * By calling this method, any custom maximum value that has been previously set is reseted,
674      * and the calculation is
675      * done automatically.
676      */
resetAxisMaximum()677     public void resetAxisMaximum() {
678         mCustomAxisMax = false;
679     }
680 
681     /**
682      * Returns true if the axis max value has been customized (and is not calculated automatically)
683      *
684      * @return
685      */
isAxisMaxCustom()686     public boolean isAxisMaxCustom() {
687         return mCustomAxisMax;
688     }
689 
690     /**
691      * By calling this method, any custom minimum value that has been previously set is reseted,
692      * and the calculation is
693      * done automatically.
694      */
resetAxisMinimum()695     public void resetAxisMinimum() {
696         mCustomAxisMin = false;
697     }
698 
699     /**
700      * Returns true if the axis min value has been customized (and is not calculated automatically)
701      *
702      * @return
703      */
isAxisMinCustom()704     public boolean isAxisMinCustom() {
705         return mCustomAxisMin;
706     }
707 
708     /**
709      * Set a custom minimum value for this axis. If set, this value will not be calculated
710      * automatically depending on
711      * the provided data. Use resetAxisMinValue() to undo this. Do not forget to call
712      * setStartAtZero(false) if you use
713      * this method. Otherwise, the axis-minimum value will still be forced to 0.
714      *
715      * @param min
716      */
setAxisMinimum(float min)717     public void setAxisMinimum(float min) {
718         mCustomAxisMin = true;
719         mAxisMinimum = min;
720         this.mAxisRange = Math.abs(mAxisMaximum - min);
721     }
722 
723     /**
724      * Use setAxisMinimum(...) instead.
725      *
726      * @param min
727      */
728     @Deprecated
setAxisMinValue(float min)729     public void setAxisMinValue(float min) {
730         setAxisMinimum(min);
731     }
732 
733     /**
734      * Set a custom maximum value for this axis. If set, this value will not be calculated
735      * automatically depending on
736      * the provided data. Use resetAxisMaxValue() to undo this.
737      *
738      * @param max
739      */
setAxisMaximum(float max)740     public void setAxisMaximum(float max) {
741         mCustomAxisMax = true;
742         mAxisMaximum = max;
743         this.mAxisRange = Math.abs(max - mAxisMinimum);
744     }
745 
746     /**
747      * Use setAxisMaximum(...) instead.
748      *
749      * @param max
750      */
751     @Deprecated
setAxisMaxValue(float max)752     public void setAxisMaxValue(float max) {
753         setAxisMaximum(max);
754     }
755 
756     /**
757      * Calculates the minimum / maximum  and range values of the axis with the given
758      * minimum and maximum values from the chart data.
759      *
760      * @param dataMin the min value according to chart data
761      * @param dataMax the max value according to chart data
762      */
calculate(float dataMin, float dataMax)763     public void calculate(float dataMin, float dataMax) {
764 
765         // if custom, use value as is, else use data value
766         float min = mCustomAxisMin ? mAxisMinimum : (dataMin - mSpaceMin);
767         float max = mCustomAxisMax ? mAxisMaximum : (dataMax + mSpaceMax);
768 
769         // temporary range (before calculations)
770         float range = Math.abs(max - min);
771 
772         // in case all values are equal
773         if (range == 0f) {
774             max = max + 1f;
775             min = min - 1f;
776         }
777 
778         this.mAxisMinimum = min;
779         this.mAxisMaximum = max;
780 
781         // actual range
782         this.mAxisRange = Math.abs(max - min);
783     }
784 
785     /**
786      * Gets extra spacing for `axisMinimum` to be added to automatically calculated `axisMinimum`
787      */
getSpaceMin()788     public float getSpaceMin()
789     {
790         return mSpaceMin;
791     }
792 
793     /**
794      * Sets extra spacing for `axisMinimum` to be added to automatically calculated `axisMinimum`
795      */
setSpaceMin(float mSpaceMin)796     public void setSpaceMin(float mSpaceMin)
797     {
798         this.mSpaceMin = mSpaceMin;
799     }
800 
801     /**
802      * Gets extra spacing for `axisMaximum` to be added to automatically calculated `axisMaximum`
803      */
getSpaceMax()804     public float getSpaceMax()
805     {
806         return mSpaceMax;
807     }
808 
809     /**
810      * Sets extra spacing for `axisMaximum` to be added to automatically calculated `axisMaximum`
811      */
setSpaceMax(float mSpaceMax)812     public void setSpaceMax(float mSpaceMax)
813     {
814         this.mSpaceMax = mSpaceMax;
815     }
816 }
817