This commit is contained in:
Philipp Jahoda 2016-08-14 21:25:52 +02:00
commit 66ea845e14
12 changed files with 668 additions and 274 deletions

View file

@ -2,6 +2,7 @@
package com.xxmassdeveloper.mpchartexample;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
@ -368,6 +369,9 @@ public class LineChartActivity1 extends DemoBase implements OnSeekBarChangeListe
set1.setDrawCircleHole(false);
set1.setValueTextSize(9f);
set1.setDrawFilled(true);
set1.setFormLineWidth(1f);
set1.setFormLineDashEffect(new DashPathEffect(new float[]{10f, 5f}, 0f));
set1.setFormSize(15.f);
if (Utils.getSDKInt() >= 18) {
// fill drawable only supported on api level 18 and above

View file

@ -222,11 +222,6 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
}
}
// make sure the graph values and grid cannot be drawn outside the
// content-rect
int clipRestoreCount = canvas.save();
canvas.clipRect(mViewPortHandler.getContentRect());
mXAxisRenderer.renderGridLines(canvas);
mAxisRendererLeft.renderGridLines(canvas);
mAxisRendererRight.renderGridLines(canvas);
@ -240,6 +235,10 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
if (mAxisRight.isDrawLimitLinesBehindDataEnabled())
mAxisRendererRight.renderLimitLines(canvas);
// make sure the data cannot be drawn outside the content-rect
int clipRestoreCount = canvas.save();
canvas.clipRect(mViewPortHandler.getContentRect());
mRenderer.drawData(canvas);
// if highlighting is enabled
@ -251,9 +250,6 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
mRenderer.drawExtras(canvas);
clipRestoreCount = canvas.save();
canvas.clipRect(mViewPortHandler.getContentRect());
if (!mXAxis.isDrawLimitLinesBehindDataEnabled())
mXAxisRenderer.renderLimitLines(canvas);
@ -262,9 +258,7 @@ public abstract class BarLineChartBase<T extends BarLineScatterCandleBubbleData<
if (!mAxisRight.isDrawLimitLinesBehindDataEnabled())
mAxisRendererRight.renderLimitLines(canvas);
canvas.restoreToCount(clipRestoreCount);
mXAxisRenderer.renderAxisLabels(canvas);
mAxisRendererLeft.renderAxisLabels(canvas);
mAxisRendererRight.renderAxisLabels(canvas);

View file

@ -115,8 +115,7 @@ public abstract class PieRadarChartBase<T extends ChartData<? extends IDataSet<?
if (mLegend != null && mLegend.isEnabled() && !mLegend.isDrawInsideEnabled()) {
float fullLegendWidth = Math.min(mLegend.mNeededWidth,
mViewPortHandler.getChartWidth() * mLegend.getMaxSizePercent()) +
mLegend.getFormSize() + mLegend.getFormToTextSpace();
mViewPortHandler.getChartWidth() * mLegend.getMaxSizePercent());
switch (mLegend.getOrientation()) {
case VERTICAL: {

View file

@ -1,8 +1,10 @@
package com.github.mikephil.charting.components;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import com.github.mikephil.charting.data.Entry;
import com.github.mikephil.charting.utils.ColorTemplate;
import com.github.mikephil.charting.utils.FSize;
import com.github.mikephil.charting.utils.Utils;
@ -33,7 +35,35 @@ public class Legend extends ComponentBase {
}
public enum LegendForm {
SQUARE, CIRCLE, LINE
/**
* Avoid drawing a form
*/
NONE,
/**
* Do not draw the a form, but leave space for it
*/
EMPTY,
/**
* Use default (default dataset's form to the legend's form)
*/
DEFAULT,
/**
* Draw a square
*/
SQUARE,
/**
* Draw a circle
*/
CIRCLE,
/**
* Draw a horizontal line
*/
LINE
}
public enum LegendHorizontalAlignment {
@ -53,27 +83,15 @@ public class Legend extends ComponentBase {
}
/**
* the legend colors array, each color is for the form drawn at the same
* index
* The legend entries array
*/
private int[] mColors;
private LegendEntry[] mEntries = new LegendEntry[]{};
/**
* the legend text array. a null label will start a group.
* Entries that will be appended to the end of the auto calculated entries after calculating the legend.
* (if the legend has already been calculated, you will need to call notifyDataSetChanged() to let the changes take effect)
*/
private String[] mLabels;
/**
* colors that will be appended to the end of the colors array after
* calculating the legend.
*/
private int[] mExtraColors;
/**
* labels that will be appended to the end of the labels array after
* calculating the legend. a null label will start a group.
*/
private String[] mExtraLabels;
private LegendEntry[] mExtraEntries;
/**
* Are the legend labels/colors a custom value or auto calculated? If false,
@ -101,6 +119,16 @@ public class Legend extends ComponentBase {
*/
private float mFormSize = 8f;
/**
* the size of the legend forms/shapes
*/
private float mFormLineWidth = 3f;
/**
* Line dash path effect used for shapes that consist of lines.
*/
private DashPathEffect mFormLineDashEffect = null;
/**
* the space between the legend entries on a horizontal axis, default 6f
*/
@ -133,22 +161,27 @@ public class Legend extends ComponentBase {
*/
public Legend() {
mFormSize = Utils.convertDpToPixel(8f);
mXEntrySpace = Utils.convertDpToPixel(6f);
mYEntrySpace = Utils.convertDpToPixel(0f);
mFormToTextSpace = Utils.convertDpToPixel(5f);
mTextSize = Utils.convertDpToPixel(10f);
mStackSpace = Utils.convertDpToPixel(3f);
this.mTextSize = Utils.convertDpToPixel(10f);
this.mXOffset = Utils.convertDpToPixel(5f);
this.mYOffset = Utils.convertDpToPixel(3f); // 2
}
/**
* Constructor. Provide colors and labels for the legend.
* Constructor. Provide entries for the legend.
*
* @param colors
* @param labels
* @param entries
*/
public Legend(LegendEntry[] entries) {
this();
if (entries == null) {
throw new IllegalArgumentException("entries array is NULL");
}
this.mEntries = entries;
}
@Deprecated
public Legend(int[] colors, String[] labels) {
this();
@ -161,56 +194,41 @@ public class Legend extends ComponentBase {
"colors array and labels array need to be of same size");
}
this.mColors = colors;
this.mLabels = labels;
List<LegendEntry> entries = new ArrayList<>();
for (int i = 0; i < Math.min(colors.length, labels.length); i++) {
final LegendEntry entry = new LegendEntry();
entry.formColor = colors[i];
entry.label = labels[i];
if (entry.formColor == ColorTemplate.COLOR_SKIP)
entry.form = LegendForm.NONE;
else if (entry.formColor == ColorTemplate.COLOR_NONE ||
entry.formColor == 0)
entry.form = LegendForm.EMPTY;
entries.add(entry);
}
mEntries = entries.toArray(new LegendEntry[entries.size()]);
}
/**
* Constructor. Provide colors and labels for the legend.
*
* @param colors
* @param labels
*/
@Deprecated
public Legend(List<Integer> colors, List<String> labels) {
this();
if (colors == null || labels == null) {
throw new IllegalArgumentException("colors array or labels array is NULL");
}
if (colors.size() != labels.size()) {
throw new IllegalArgumentException(
"colors array and labels array need to be of same size");
}
this.mColors = Utils.convertIntegers(colors);
this.mLabels = Utils.convertStrings(labels);
this(Utils.convertIntegers(colors), Utils.convertStrings(labels));
}
/**
* This method sets the automatically computed colors for the legend. Use setCustom(...) to set custom colors.
*
* @param colors
* @param entries
*/
public void setComputedColors(List<Integer> colors) {
if (mColors != null && colors.size() == mColors.length) {
Utils.copyIntegers(colors, mColors);
} else {
mColors = Utils.convertIntegers(colors);
}
public void setEntries(List<LegendEntry> entries) {
mEntries = entries.toArray(new LegendEntry[entries.size()]);
}
/**
* This method sets the automatically computed labels for the legend. Use setCustom(...) to set custom labels.
*
* @param labels
*/
public void setComputedLabels(List<String> labels) {
if (mLabels != null && mLabels.length == labels.size()) {
Utils.copyStrings(labels, mLabels);
} else {
mLabels = Utils.convertStrings(labels);
}
public LegendEntry[] getEntries() {
return mEntries;
}
/**
@ -223,19 +241,26 @@ public class Legend extends ComponentBase {
public float getMaximumEntryWidth(Paint p) {
float max = 0f;
float maxFormSize = 0f;
float formToTextSpace = Utils.convertDpToPixel(mFormToTextSpace);
for (int i = 0; i < mLabels.length; i++) {
for (LegendEntry entry : mEntries) {
final float formSize = Utils.convertDpToPixel(
Float.isNaN(entry.formSize)
? mFormSize : entry.formSize);
if (formSize > maxFormSize)
maxFormSize = formSize;
if (mLabels[i] != null) {
String label = entry.label;
if (label == null) continue;
float length = (float) Utils.calcTextWidth(p, mLabels[i]);
float length = (float) Utils.calcTextWidth(p, label);
if (length > max)
max = length;
}
if (length > max)
max = length;
}
return max + mFormSize + mFormToTextSpace;
return max + maxFormSize + formToTextSpace;
}
/**
@ -248,140 +273,141 @@ public class Legend extends ComponentBase {
float max = 0f;
for (int i = 0; i < mLabels.length; i++) {
for (LegendEntry entry : mEntries) {
String label = entry.label;
if (label == null) continue;
if (mLabels[i] != null) {
float length = (float) Utils.calcTextHeight(p, label);
float length = (float) Utils.calcTextHeight(p, mLabels[i]);
if (length > max)
max = length;
}
if (length > max)
max = length;
}
return max;
}
/**
* returns all the colors the legend uses
*
* @return
*/
@Deprecated
public int[] getColors() {
return mColors;
int[] old = new int[mEntries.length];
for (int i = 0; i < mEntries.length; i++) {
old[i] = mEntries[i].form == LegendForm.NONE ? ColorTemplate.COLOR_SKIP :
(mEntries[i].form == LegendForm.EMPTY ? ColorTemplate.COLOR_NONE :
mEntries[i].formColor);
}
return old;
}
/**
* returns all the labels the legend uses
*
* @return
*/
@Deprecated
public String[] getLabels() {
return mLabels;
String[] old = new String[mEntries.length];
for (int i = 0; i < mEntries.length; i++) {
old[i] = mEntries[i].label;
}
return old;
}
/**
* Returns the legend-label at the given index.
*
* @param index
* @return
*/
public String getLabel(int index) {
return mLabels[index];
}
/**
* colors that will be appended to the end of the colors array after
* calculating the legend.
*/
@Deprecated
public int[] getExtraColors() {
return mExtraColors;
int[] old = new int[mExtraEntries.length];
for (int i = 0; i < mExtraEntries.length; i++) {
old[i] = mExtraEntries[i].form == LegendForm.NONE ? ColorTemplate.COLOR_SKIP :
(mExtraEntries[i].form == LegendForm.EMPTY ? ColorTemplate.COLOR_NONE :
mExtraEntries[i].formColor);
}
return old;
}
/**
* labels that will be appended to the end of the labels array after
* calculating the legend. a null label will start a group.
*/
@Deprecated
public String[] getExtraLabels() {
return mExtraLabels;
String[] old = new String[mExtraEntries.length];
for (int i = 0; i < mExtraEntries.length; i++) {
old[i] = mExtraEntries[i].label;
}
return old;
}
/**
* Colors and labels that will be appended to the end of the auto calculated
* colors and labels arrays after calculating the legend. (if the legend has
* already been calculated, you will need to call notifyDataSetChanged() to
* let the changes take effect)
*/
public LegendEntry[] getExtraEntries() {
return mExtraEntries;
}
public void setExtra(List<LegendEntry> entries) {
mExtraEntries = entries.toArray(new LegendEntry[entries.size()]);
}
public void setExtra(LegendEntry[] entries) {
if (entries == null)
entries = new LegendEntry[]{};
mExtraEntries = entries;
}
@Deprecated
public void setExtra(List<Integer> colors, List<String> labels) {
if (mExtraColors != null && mExtraColors.length == colors.size()) {
Utils.copyIntegers(colors, mExtraColors);
} else {
this.mExtraColors = Utils.convertIntegers(colors);
}
if (mExtraLabels != null && mExtraLabels.length == labels.size()) {
Utils.copyStrings(labels, mExtraLabels);
} else {
this.mExtraLabels = Utils.convertStrings(labels);
}
setExtra(Utils.convertIntegers(colors), Utils.convertStrings(labels));
}
/**
* Colors and labels that will be appended to the end of the auto calculated
* colors and labels arrays after calculating the legend. (if the legend has
* already been calculated, you will need to call notifyDataSetChanged() to
* let the changes take effect)
* Entries that will be appended to the end of the auto calculated
* entries after calculating the legend.
* (if the legend has already been calculated, you will need to call notifyDataSetChanged()
* to let the changes take effect)
*/
public void setExtra(int[] colors, String[] labels) {
this.mExtraColors = colors;
this.mExtraLabels = labels;
List<LegendEntry> entries = new ArrayList<>();
for (int i = 0; i < Math.min(colors.length, labels.length); i++) {
final LegendEntry entry = new LegendEntry();
entry.formColor = colors[i];
entry.label = labels[i];
if (entry.formColor == ColorTemplate.COLOR_SKIP ||
entry.formColor == 0)
entry.form = LegendForm.NONE;
else if (entry.formColor == ColorTemplate.COLOR_NONE)
entry.form = LegendForm.EMPTY;
entries.add(entry);
}
mExtraEntries = entries.toArray(new LegendEntry[entries.size()]);
}
/**
* Sets a custom legend's labels and colors arrays. The colors count should
* match the labels count. * Each color is for the form drawn at the same
* index. * A null label will start a group. * A ColorTemplate.COLOR_SKIP
* color will avoid drawing a form This will disable the feature that
* automatically calculates the legend labels and colors from the datasets.
* Sets a custom legend's entries array.
* * A null label will start a group.
* This will disable the feature that automatically calculates the legend
* entries from the datasets.
* Call resetCustom() to re-enable automatic calculation (and then
* notifyDataSetChanged() is needed to auto-calculate the legend again)
* notifyDataSetChanged() is needed to auto-calculate the legend again)
*/
public void setCustom(int[] colors, String[] labels) {
public void setCustom(LegendEntry[] entries) {
if (colors.length != labels.length) {
throw new IllegalArgumentException(
"colors array and labels array need to be of same size");
}
mLabels = labels;
mColors = colors;
mEntries = entries;
mIsLegendCustom = true;
}
/**
* Sets a custom legend's labels and colors arrays. The colors count should
* match the labels count. * Each color is for the form drawn at the same
* index. * A null label will start a group. * A ColorTemplate.COLOR_SKIP
* color will avoid drawing a form This will disable the feature that
* automatically calculates the legend labels and colors from the datasets.
* Sets a custom legend's entries array.
* * A null label will start a group.
* This will disable the feature that automatically calculates the legend
* entries from the datasets.
* Call resetCustom() to re-enable automatic calculation (and then
* notifyDataSetChanged() is needed to auto-calculate the legend again)
* notifyDataSetChanged() is needed to auto-calculate the legend again)
*/
public void setCustom(List<Integer> colors, List<String> labels) {
public void setCustom(List<LegendEntry> entries) {
if (colors.size() != labels.size()) {
throw new IllegalArgumentException(
"colors array and labels array need to be of same size");
}
mColors = Utils.convertIntegers(colors);
mLabels = Utils.convertStrings(labels);
mEntries = entries.toArray(new LegendEntry[entries.size()]);
mIsLegendCustom = true;
}
/**
* Calling this will disable the custom legend labels (set by
* setCustom(...)). Instead, the labels will again be calculated
* Calling this will disable the custom legend entries (set by
* setCustom(...)). Instead, the entries will again be calculated
* automatically (after notifyDataSetChanged() is called).
*/
public void resetCustom() {
@ -389,7 +415,7 @@ public class Legend extends ComponentBase {
}
/**
* @return true if a custom legend labels and colors has been set default
* @return true if a custom legend entries has been set default
* false (automatic legend)
*/
public boolean isLegendCustom() {
@ -608,13 +634,12 @@ public class Legend extends ComponentBase {
}
/**
* sets the size in pixels of the legend forms, this is internally converted
* in dp, default 8f
* sets the size in dp of the legend forms, default 8f
*
* @param size
*/
public void setFormSize(float size) {
mFormSize = Utils.convertDpToPixel(size);
mFormSize = size;
}
/**
@ -626,6 +651,40 @@ public class Legend extends ComponentBase {
return mFormSize;
}
/**
* sets the line width in dp for forms that consist of lines, default 3f
*
* @param size
*/
public void setFormLineWidth(float size) {
mFormLineWidth = size;
}
/**
* returns the line width in dp for drawing forms that consist of lines
*
* @return
*/
public float getFormLineWidth() {
return mFormLineWidth;
}
/**
* Sets the line dash path effect used for shapes that consist of lines.
*
* @param dashPathEffect
*/
public void setFormLineDashEffect(DashPathEffect dashPathEffect) {
mFormLineDashEffect = dashPathEffect;
}
/**
* @return The line dash path effect used for shapes that consist of lines.
*/
public DashPathEffect getFormLineDashEffect() {
return mFormLineDashEffect;
}
/**
* returns the space between the legend entries on a horizontal axis in
* pixels
@ -643,7 +702,7 @@ public class Legend extends ComponentBase {
* @param space
*/
public void setXEntrySpace(float space) {
mXEntrySpace = Utils.convertDpToPixel(space);
mXEntrySpace = space;
}
/**
@ -662,7 +721,7 @@ public class Legend extends ComponentBase {
* @param space
*/
public void setYEntrySpace(float space) {
mYEntrySpace = Utils.convertDpToPixel(space);
mYEntrySpace = space;
}
/**
@ -681,7 +740,7 @@ public class Legend extends ComponentBase {
* @param space
*/
public void setFormToTextSpace(float space) {
this.mFormToTextSpace = Utils.convertDpToPixel(space);
this.mFormToTextSpace = space;
}
/**
@ -795,6 +854,15 @@ public class Legend extends ComponentBase {
*/
public void calculateDimensions(Paint labelpaint, ViewPortHandler viewPortHandler) {
float defaultFormSize = Utils.convertDpToPixel(mFormSize);
float stackSpace = Utils.convertDpToPixel(mStackSpace);
float formToTextSpace = Utils.convertDpToPixel(mFormToTextSpace);
float xEntrySpace = Utils.convertDpToPixel(mXEntrySpace);
float yEntrySpace = Utils.convertDpToPixel(mYEntrySpace);
boolean wordWrapEnabled = mWordWrapEnabled;
LegendEntry[] entries = mEntries;
int entryCount = entries.length;
mTextWidthMax = getMaximumEntryWidth(labelpaint);
mTextHeightMax = getMaximumEntryHeight(labelpaint);
@ -803,44 +871,48 @@ public class Legend extends ComponentBase {
float maxWidth = 0f, maxHeight = 0f, width = 0f;
float labelLineHeight = Utils.getLineHeight(labelpaint);
final int count = mLabels.length;
boolean wasStacked = false;
for (int i = 0; i < count; i++) {
for (int i = 0; i < entryCount; i++) {
boolean drawingForm = mColors[i] != ColorTemplate.COLOR_SKIP;
LegendEntry e = entries[i];
boolean drawingForm = e.form != LegendForm.NONE;
float formSize = Float.isNaN(e.formSize)
? defaultFormSize
: Utils.convertDpToPixel(e.formSize);
String label = e.label;
if (!wasStacked)
width = 0.f;
if (drawingForm) {
if (wasStacked)
width += mStackSpace;
width += mFormSize;
width += stackSpace;
width += formSize;
}
// grouped forms have null labels
if (mLabels[i] != null) {
if (label != null) {
// make a step to the left
if (drawingForm && !wasStacked)
width += mFormToTextSpace;
width += formToTextSpace;
else if (wasStacked) {
maxWidth = Math.max(maxWidth, width);
maxHeight += labelLineHeight + mYEntrySpace;
maxHeight += labelLineHeight + yEntrySpace;
width = 0.f;
wasStacked = false;
}
width += Utils.calcTextWidth(labelpaint, mLabels[i]);
width += Utils.calcTextWidth(labelpaint, label);
if (i < count - 1)
maxHeight += labelLineHeight + mYEntrySpace;
if (i < entryCount - 1)
maxHeight += labelLineHeight + yEntrySpace;
} else {
wasStacked = true;
width += mFormSize;
if (i < count - 1)
width += mStackSpace;
width += formSize;
if (i < entryCount - 1)
width += stackSpace;
}
maxWidth = Math.max(maxWidth, width);
@ -853,9 +925,8 @@ public class Legend extends ComponentBase {
}
case HORIZONTAL: {
int labelCount = mLabels.length;
float labelLineHeight = Utils.getLineHeight(labelpaint);
float labelLineSpacing = Utils.getLineSpacing(labelpaint) + mYEntrySpace;
float labelLineSpacing = Utils.getLineSpacing(labelpaint) + yEntrySpace;
float contentWidth = viewPortHandler.contentWidth() * mMaxSizePercent;
// Start calculating layout
@ -868,9 +939,14 @@ public class Legend extends ComponentBase {
mCalculatedLabelSizes.clear();
mCalculatedLineSizes.clear();
for (int i = 0; i < labelCount; i++) {
for (int i = 0; i < entryCount; i++) {
boolean drawingForm = mColors[i] != ColorTemplate.COLOR_SKIP;
LegendEntry e = entries[i];
boolean drawingForm = e.form != LegendForm.NONE;
float formSize = Float.isNaN(e.formSize)
? defaultFormSize
: Utils.convertDpToPixel(e.formSize);
String label = e.label;
mCalculatedLabelBreakPoints.add(false);
@ -880,19 +956,19 @@ public class Legend extends ComponentBase {
requiredWidth = 0.f;
} else {
// add the spacing appropriate for stacked labels/forms
requiredWidth += mStackSpace;
requiredWidth += stackSpace;
}
// grouped forms have null labels
if (mLabels[i] != null) {
if (label != null) {
mCalculatedLabelSizes.add(Utils.calcTextSize(labelpaint, mLabels[i]));
requiredWidth += drawingForm ? mFormToTextSpace + mFormSize : 0.f;
mCalculatedLabelSizes.add(Utils.calcTextSize(labelpaint, label));
requiredWidth += drawingForm ? formToTextSpace + formSize : 0.f;
requiredWidth += mCalculatedLabelSizes.get(i).width;
} else {
mCalculatedLabelSizes.add(FSize.getInstance(0.f, 0.f));
requiredWidth += drawingForm ? mFormSize : 0.f;
requiredWidth += drawingForm ? formSize : 0.f;
if (stackedStartIndex == -1) {
// mark this index as we might want to break here later
@ -900,11 +976,11 @@ public class Legend extends ComponentBase {
}
}
if (mLabels[i] != null || i == labelCount - 1) {
if (label != null || i == entryCount - 1) {
float requiredSpacing = currentLineWidth == 0.f ? 0.f : mXEntrySpace;
float requiredSpacing = currentLineWidth == 0.f ? 0.f : xEntrySpace;
if (!mWordWrapEnabled // No word wrapping, it must fit.
if (!wordWrapEnabled // No word wrapping, it must fit.
// The line is empty, it must fit
|| currentLineWidth == 0.f
// It simply fits
@ -925,14 +1001,14 @@ public class Legend extends ComponentBase {
currentLineWidth = requiredWidth;
}
if (i == labelCount - 1) {
if (i == entryCount - 1) {
// Add last line size to array
mCalculatedLineSizes.add(FSize.getInstance(currentLineWidth, labelLineHeight));
maxLineWidth = Math.max(maxLineWidth, currentLineWidth);
}
}
stackedStartIndex = mLabels[i] != null ? -1 : stackedStartIndex;
stackedStartIndex = label != null ? -1 : stackedStartIndex;
}
mNeededWidth = maxLineWidth;

View file

@ -0,0 +1,78 @@
package com.github.mikephil.charting.components;
import android.graphics.DashPathEffect;
import com.github.mikephil.charting.utils.ColorTemplate;
public class LegendEntry {
public LegendEntry() {
}
/**
*
* @param label The legend entry text. A `null` label will start a group.
* @param form The form to draw for this entry.
* @param formSize Set to NaN to use the legend's default.
* @param formLineWidth Set to NaN to use the legend's default.
* @param formLineDashEffect Set to nil to use the legend's default.
* @param formColor The color for drawing the form.
*/
public LegendEntry(String label,
Legend.LegendForm form,
float formSize,
float formLineWidth,
DashPathEffect formLineDashEffect,
int formColor)
{
this.label = label;
this.form = form;
this.formSize = formSize;
this.formLineWidth = formLineWidth;
this.formLineDashEffect = formLineDashEffect;
this.formColor = formColor;
}
/**
* The legend entry text.
* A `null` label will start a group.
*/
public String label;
/**
* The form to draw for this entry.
*
* `NONE` will avoid drawing a form, and any related space.
* `EMPTY` will avoid drawing a form, but keep its space.
* `DEFAULT` will use the Legend's default.
*/
public Legend.LegendForm form = Legend.LegendForm.DEFAULT;
/**
* Form size will be considered except for when .None is used
*
* Set as NaN to use the legend's default
*/
public float formSize = Float.NaN;
/**
* Line width used for shapes that consist of lines.
*
* Set as NaN to use the legend's default
*/
public float formLineWidth = Float.NaN;
/**
* Line dash path effect used for shapes that consist of lines.
*
* Set to null to use the legend's default
*/
public DashPathEffect formLineDashEffect = null;
/**
* The color for drawing the form
*/
public int formColor = ColorTemplate.COLOR_NONE;
}

View file

@ -2,8 +2,10 @@ package com.github.mikephil.charting.data;
import android.content.Context;
import android.graphics.Color;
import android.graphics.DashPathEffect;
import android.graphics.Typeface;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.formatter.DefaultValueFormatter;
import com.github.mikephil.charting.formatter.IValueFormatter;
@ -56,6 +58,11 @@ public abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
*/
protected Typeface mValueTypeface;
private Legend.LegendForm mForm = Legend.LegendForm.DEFAULT;
private float mFormSize = Float.NaN;
private float mFormLineWidth = Float.NaN;
private DashPathEffect mFormLineDashEffect = null;
/**
* if true, y-values are drawn on the chart
*/
@ -318,6 +325,42 @@ public abstract class BaseDataSet<T extends Entry> implements IDataSet<T> {
return mValueTextSize;
}
public void setForm(Legend.LegendForm form) {
mForm = form;
}
@Override
public Legend.LegendForm getForm() {
return mForm;
}
public void setFormSize(float formSize) {
mFormSize = formSize;
}
@Override
public float getFormSize() {
return mFormSize;
}
public void setFormLineWidth(float formLineWidth) {
mFormLineWidth = formLineWidth;
}
@Override
public float getFormLineWidth() {
return mFormLineWidth;
}
public void setFormLineDashEffect(DashPathEffect dashPathEffect) {
mFormLineDashEffect = dashPathEffect;
}
@Override
public DashPathEffect getFormLineDashEffect() {
return mFormLineDashEffect;
}
@Override
public void setDrawValues(boolean enabled) {
this.mDrawValues = enabled;

View file

@ -1,7 +1,9 @@
package com.github.mikephil.charting.interfaces.datasets;
import android.graphics.DashPathEffect;
import android.graphics.Typeface;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.YAxis;
import com.github.mikephil.charting.data.DataSet;
import com.github.mikephil.charting.data.Entry;
@ -368,6 +370,34 @@ public interface IDataSet<T extends Entry> {
*/
float getValueTextSize();
/**
* The form to draw for this dataset in the legend.
*
* Return `DEFAULT` to use the default legend form.
*/
Legend.LegendForm getForm();
/**
* The form size to draw for this dataset in the legend.
*
* Return `Float.NaN` to use the default legend form size.
*/
float getFormSize();
/**
* The line width for drawing the form of this dataset in the legend
*
* Return `Float.NaN` to use the default legend form line width.
*/
float getFormLineWidth();
/**
* The line dash path effect used for shapes that consist of lines.
*
* Return `null` to use the default legend form line dash effect.
*/
DashPathEffect getFormLineDashEffect();
/**
* set this to true to draw y-values on the chart NOTE (for bar and
* linechart): if "maxvisiblecount" is reached, no values will be drawn even

View file

@ -2,11 +2,14 @@
package com.github.mikephil.charting.renderer;
import android.graphics.Canvas;
import android.graphics.DashPathEffect;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Path;
import android.graphics.Typeface;
import com.github.mikephil.charting.components.Legend;
import com.github.mikephil.charting.components.LegendEntry;
import com.github.mikephil.charting.data.ChartData;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
import com.github.mikephil.charting.interfaces.datasets.ICandleDataSet;
@ -49,7 +52,6 @@ public class LegendRenderer extends Renderer {
mLegendFormPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mLegendFormPaint.setStyle(Paint.Style.FILL);
mLegendFormPaint.setStrokeWidth(3f);
}
/**
@ -71,8 +73,7 @@ public class LegendRenderer extends Renderer {
}
protected List<String> computedLabels = new ArrayList<>(16);
protected List<Integer> computedColors = new ArrayList<>(16);
protected List<LegendEntry> computedEntries = new ArrayList<>(16);
/**
* Prepares the legend and calculates all needed forms, labels and colors.
@ -83,8 +84,7 @@ public class LegendRenderer extends Renderer {
if (!mLegend.isLegendCustom()) {
computedLabels.clear();
computedColors.clear();
computedEntries.clear();
// loop for building up the colors and labels used in the legend
for (int i = 0; i < data.getDataSetCount(); i++) {
@ -102,14 +102,26 @@ public class LegendRenderer extends Renderer {
for (int j = 0; j < clrs.size() && j < bds.getStackSize(); j++) {
computedLabels.add(sLabels[j % sLabels.length]);
computedColors.add(clrs.get(j));
computedEntries.add(new LegendEntry(
sLabels[j % sLabels.length],
dataSet.getForm(),
dataSet.getFormSize(),
dataSet.getFormLineWidth(),
dataSet.getFormLineDashEffect(),
clrs.get(j)
));
}
if (bds.getLabel() != null) {
// add the legend description label
computedColors.add(ColorTemplate.COLOR_SKIP);
computedLabels.add(bds.getLabel());
computedEntries.add(new LegendEntry(
dataSet.getLabel(),
Legend.LegendForm.NONE,
Float.NaN,
Float.NaN,
null,
ColorTemplate.COLOR_NONE
));
}
} else if (dataSet instanceof IPieDataSet) {
@ -118,55 +130,82 @@ public class LegendRenderer extends Renderer {
for (int j = 0; j < clrs.size() && j < entryCount; j++) {
computedLabels.add(pds.getEntryForIndex(j).getLabel());
computedColors.add(clrs.get(j));
computedEntries.add(new LegendEntry(
pds.getEntryForIndex(j).getLabel(),
dataSet.getForm(),
dataSet.getFormSize(),
dataSet.getFormLineWidth(),
dataSet.getFormLineDashEffect(),
clrs.get(j)
));
}
if (pds.getLabel() != null) {
// add the legend description label
computedColors.add(ColorTemplate.COLOR_SKIP);
computedLabels.add(pds.getLabel());
computedEntries.add(new LegendEntry(
dataSet.getLabel(),
Legend.LegendForm.NONE,
Float.NaN,
Float.NaN,
null,
ColorTemplate.COLOR_NONE
));
}
} else if (dataSet instanceof ICandleDataSet && ((ICandleDataSet) dataSet).getDecreasingColor() !=
ColorTemplate.COLOR_NONE) {
int decreasingColor = ((ICandleDataSet) dataSet).getDecreasingColor();
computedColors.add(decreasingColor);
int increasingColor = ((ICandleDataSet) dataSet).getIncreasingColor();
computedColors.add(increasingColor);
computedLabels.add(null);
computedLabels.add(dataSet.getLabel());
computedEntries.add(new LegendEntry(
null,
dataSet.getForm(),
dataSet.getFormSize(),
dataSet.getFormLineWidth(),
dataSet.getFormLineDashEffect(),
decreasingColor
));
computedEntries.add(new LegendEntry(
dataSet.getLabel(),
dataSet.getForm(),
dataSet.getFormSize(),
dataSet.getFormLineWidth(),
dataSet.getFormLineDashEffect(),
increasingColor
));
} else { // all others
for (int j = 0; j < clrs.size() && j < entryCount; j++) {
String label;
// if multiple colors are set for a DataSet, group them
if (j < clrs.size() - 1 && j < entryCount - 1) {
computedLabels.add(null);
label = null;
} else { // add label to the last entry
String label = data.getDataSetByIndex(i).getLabel();
computedLabels.add(label);
label = data.getDataSetByIndex(i).getLabel();
}
computedColors.add(clrs.get(j));
computedEntries.add(new LegendEntry(
label,
dataSet.getForm(),
dataSet.getFormSize(),
dataSet.getFormLineWidth(),
dataSet.getFormLineDashEffect(),
clrs.get(j)
));
}
}
}
if (mLegend.getExtraColors() != null && mLegend.getExtraLabels() != null) {
for (int color : mLegend.getExtraColors())
computedColors.add(color);
Collections.addAll(computedLabels, mLegend.getExtraLabels());
if (mLegend.getExtraEntries() != null) {
Collections.addAll(computedEntries, mLegend.getExtraEntries());
}
mLegend.setComputedColors(computedColors);
mLegend.setComputedLabels(computedLabels);
mLegend.setEntries(computedEntries);
}
Typeface tf = mLegend.getTypeface();
@ -197,22 +236,22 @@ public class LegendRenderer extends Renderer {
mLegendLabelPaint.setColor(mLegend.getTextColor());
float labelLineHeight = Utils.getLineHeight(mLegendLabelPaint, legendFontMetrics);
float labelLineSpacing = Utils.getLineSpacing(mLegendLabelPaint, legendFontMetrics) + mLegend.getYEntrySpace();
float labelLineSpacing = Utils.getLineSpacing(mLegendLabelPaint, legendFontMetrics)
+ Utils.convertDpToPixel(mLegend.getYEntrySpace());
float formYOffset = labelLineHeight - Utils.calcTextHeight(mLegendLabelPaint, "ABC") / 2.f;
String[] labels = mLegend.getLabels();
int[] colors = mLegend.getColors();
LegendEntry[] entries = mLegend.getEntries();
float formToTextSpace = mLegend.getFormToTextSpace();
float xEntrySpace = mLegend.getXEntrySpace();
float formToTextSpace = Utils.convertDpToPixel(mLegend.getFormToTextSpace());
float xEntrySpace = Utils.convertDpToPixel(mLegend.getXEntrySpace());
Legend.LegendOrientation orientation = mLegend.getOrientation();
Legend.LegendHorizontalAlignment horizontalAlignment = mLegend.getHorizontalAlignment();
Legend.LegendVerticalAlignment verticalAlignment = mLegend.getVerticalAlignment();
Legend.LegendDirection direction = mLegend.getDirection();
float formSize = mLegend.getFormSize();
float defaultFormSize = Utils.convertDpToPixel(mLegend.getFormSize());
// space between the entries
float stackSpace = mLegend.getStackSpace();
float stackSpace = Utils.convertDpToPixel(mLegend.getStackSpace());
float yoffset = mLegend.getYOffset();
float xoffset = mLegend.getXOffset();
@ -292,7 +331,12 @@ public class LegendRenderer extends Renderer {
int lineIndex = 0;
for (int i = 0, count = labels.length; i < count; i++) {
for (int i = 0, count = entries.length; i < count; i++) {
LegendEntry e = entries[i];
boolean drawingForm = e.form != Legend.LegendForm.NONE;
float formSize = Float.isNaN(e.formSize) ? defaultFormSize : Utils.convertDpToPixel(e.formSize);
if (i < calculatedLabelBreakPoints.size() && calculatedLabelBreakPoints.get(i)) {
posX = originPosX;
posY += labelLineHeight + labelLineSpacing;
@ -307,14 +351,13 @@ public class LegendRenderer extends Renderer {
lineIndex++;
}
boolean drawingForm = colors[i] != ColorTemplate.COLOR_SKIP;
boolean isStacked = labels[i] == null; // grouped forms have null labels
boolean isStacked = e.label == null; // grouped forms have null labels
if (drawingForm) {
if (direction == Legend.LegendDirection.RIGHT_TO_LEFT)
posX -= formSize;
drawForm(c, posX, posY + formYOffset, i, mLegend);
drawForm(c, posX, posY + formYOffset, e, mLegend);
if (direction == Legend.LegendDirection.LEFT_TO_RIGHT)
posX += formSize;
@ -328,7 +371,7 @@ public class LegendRenderer extends Renderer {
if (direction == Legend.LegendDirection.RIGHT_TO_LEFT)
posX -= calculatedLabelSizes.get(i).width;
drawLabel(c, posX, posY + labelLineHeight, labels[i]);
drawLabel(c, posX, posY + labelLineHeight, e.label);
if (direction == Legend.LegendDirection.LEFT_TO_RIGHT)
posX += calculatedLabelSizes.get(i).width;
@ -369,9 +412,12 @@ public class LegendRenderer extends Renderer {
break;
}
for (int i = 0; i < labels.length; i++) {
for (int i = 0; i < entries.length; i++) {
LegendEntry e = entries[i];
boolean drawingForm = e.form != Legend.LegendForm.NONE;
float formSize = Float.isNaN(e.formSize) ? defaultFormSize : Utils.convertDpToPixel(e.formSize);
Boolean drawingForm = colors[i] != ColorTemplate.COLOR_SKIP;
float posX = originPosX;
if (drawingForm) {
@ -380,13 +426,13 @@ public class LegendRenderer extends Renderer {
else
posX -= formSize - stack;
drawForm(c, posX, posY + formYOffset, i, mLegend);
drawForm(c, posX, posY + formYOffset, e, mLegend);
if (direction == Legend.LegendDirection.LEFT_TO_RIGHT)
posX += formSize;
}
if (labels[i] != null) {
if (e.label != null) {
if (drawingForm && !wasStacked)
posX += direction == Legend.LegendDirection.LEFT_TO_RIGHT ? formToTextSpace
@ -395,13 +441,13 @@ public class LegendRenderer extends Renderer {
posX = originPosX;
if (direction == Legend.LegendDirection.RIGHT_TO_LEFT)
posX -= Utils.calcTextWidth(mLegendLabelPaint, labels[i]);
posX -= Utils.calcTextWidth(mLegendLabelPaint, e.label);
if (!wasStacked) {
drawLabel(c, posX, posY + labelLineHeight, labels[i]);
drawLabel(c, posX, posY + labelLineHeight, e.label);
} else {
posY += labelLineHeight + labelLineSpacing;
drawLabel(c, posX, posY + labelLineHeight, labels[i]);
drawLabel(c, posX, posY + labelLineHeight, e.label);
}
// make a step down
@ -419,36 +465,85 @@ public class LegendRenderer extends Renderer {
}
}
private Path mLineFormPath = new Path();
/**
* Draws the Legend-form at the given position with the color at the given
* index.
*
* @param c canvas to draw with
* @param x position
* @param y position
* @param index the index of the color to use (in the colors array)
* @param c canvas to draw with
* @param x position
* @param y position
* @param entry the entry to render
* @param legend the legend context
*/
protected void drawForm(Canvas c, float x, float y, int index, Legend legend) {
protected void drawForm(
Canvas c,
float x, float y,
LegendEntry entry,
Legend legend) {
if (legend.getColors()[index] == ColorTemplate.COLOR_SKIP)
if (entry.formColor == ColorTemplate.COLOR_SKIP ||
entry.formColor == ColorTemplate.COLOR_NONE ||
entry.formColor == 0)
return;
mLegendFormPaint.setColor(legend.getColors()[index]);
int restoreCount = c.save();
float formsize = legend.getFormSize();
float half = formsize / 2f;
Legend.LegendForm form = entry.form;
if (form == Legend.LegendForm.DEFAULT)
form = legend.getForm();
switch (legend.getForm()) {
mLegendFormPaint.setColor(entry.formColor);
final float formSize = Utils.convertDpToPixel(
Float.isNaN(entry.formSize)
? legend.getFormSize()
: entry.formSize);
final float half = formSize / 2f;
switch (form) {
case NONE:
// Do nothing
break;
case EMPTY:
// Do not draw, but keep space for the form
break;
case DEFAULT:
case CIRCLE:
mLegendFormPaint.setStyle(Paint.Style.FILL);
c.drawCircle(x + half, y, half, mLegendFormPaint);
break;
case SQUARE:
c.drawRect(x, y - half, x + formsize, y + half, mLegendFormPaint);
mLegendFormPaint.setStyle(Paint.Style.FILL);
c.drawRect(x, y - half, x + formSize, y + half, mLegendFormPaint);
break;
case LINE:
c.drawLine(x, y, x + formsize, y, mLegendFormPaint);
{
final float formLineWidth = Utils.convertDpToPixel(
Float.isNaN(entry.formLineWidth)
? legend.getFormLineWidth()
: entry.formLineWidth);
final DashPathEffect formLineDashEffect = entry.formLineDashEffect == null
? legend.getFormLineDashEffect()
: entry.formLineDashEffect;
mLegendFormPaint.setStyle(Paint.Style.STROKE);
mLegendFormPaint.setStrokeWidth(formLineWidth);
mLegendFormPaint.setPathEffect(formLineDashEffect);
mLineFormPath.reset();
mLineFormPath.moveTo(x, y);
mLineFormPath.lineTo(x + formSize, y);
c.drawPath(mLineFormPath, mLegendFormPaint);
}
break;
}
c.restoreToCount(restoreCount);
}
/**

View file

@ -6,6 +6,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Path;
import android.graphics.RectF;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.XAxis;
@ -236,6 +237,9 @@ public class XAxisRenderer extends AxisRenderer {
if (!mXAxis.isDrawGridLinesEnabled() || !mXAxis.isEnabled())
return;
int clipRestoreCount = c.save();
c.clipRect(getGridClippingRect());
if(mRenderGridLinesBuffer.length != mAxis.mEntryCount * 2){
mRenderGridLinesBuffer = new float[mXAxis.mEntryCount * 2];
}
@ -257,6 +261,16 @@ public class XAxisRenderer extends AxisRenderer {
drawGridLine(c, positions[i], positions[i + 1], gridLinePath);
}
c.restoreToCount(clipRestoreCount);
}
protected RectF mGridClippingRect = new RectF();
public RectF getGridClippingRect() {
mGridClippingRect.set(mViewPortHandler.getContentRect());
mGridClippingRect.inset(-mAxis.getGridLineWidth() / 2.f, 0.f);
return mGridClippingRect;
}
/**
@ -279,6 +293,8 @@ public class XAxisRenderer extends AxisRenderer {
}
protected float[] mRenderLimitLinesBuffer = new float[2];
protected RectF mLimitLineClippingRect = new RectF();
/**
* Draws the LimitLines associated with this axis to the screen.
*
@ -303,6 +319,11 @@ public class XAxisRenderer extends AxisRenderer {
if (!l.isEnabled())
continue;
int clipRestoreCount = c.save();
mLimitLineClippingRect.set(mViewPortHandler.getContentRect());
mLimitLineClippingRect.inset(-l.getLineWidth() / 2.f, 0.f);
c.clipRect(mLimitLineClippingRect);
position[0] = l.getLimit();
position[1] = 0.f;
@ -310,6 +331,8 @@ public class XAxisRenderer extends AxisRenderer {
renderLimitLineLine(c, l, position);
renderLimitLineLabel(c, l, position, 2.f + l.getYOffset());
c.restoreToCount(clipRestoreCount);
}
}

View file

@ -5,6 +5,7 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Path;
import android.graphics.RectF;
import com.github.mikephil.charting.charts.BarChart;
import com.github.mikephil.charting.components.LimitLine;
@ -161,6 +162,13 @@ public class XAxisRendererHorizontalBarChart extends XAxisRenderer {
}
}
@Override
public RectF getGridClippingRect() {
mGridClippingRect.set(mViewPortHandler.getContentRect());
mGridClippingRect.inset(0.f, -mAxis.getGridLineWidth() / 2.f);
return mGridClippingRect;
}
@Override
protected void drawGridLine(Canvas c, float x, float y, Path gridLinePath) {
@ -228,6 +236,11 @@ public class XAxisRendererHorizontalBarChart extends XAxisRenderer {
if(!l.isEnabled())
continue;
int clipRestoreCount = c.save();
mLimitLineClippingRect.set(mViewPortHandler.getContentRect());
mLimitLineClippingRect.inset(0.f, -l.getLineWidth() / 2.f);
c.clipRect(mLimitLineClippingRect);
mLimitLinePaint.setStyle(Paint.Style.STROKE);
mLimitLinePaint.setColor(l.getLineColor());
mLimitLinePaint.setStrokeWidth(l.getLineWidth());
@ -290,6 +303,8 @@ public class XAxisRendererHorizontalBarChart extends XAxisRenderer {
pts[1] + yOffset, mLimitLinePaint);
}
}
c.restoreToCount(clipRestoreCount);
}
}
}

View file

@ -5,6 +5,7 @@ import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Path;
import android.graphics.RectF;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.YAxis;
@ -134,6 +135,9 @@ public class YAxisRenderer extends AxisRenderer {
if (mYAxis.isDrawGridLinesEnabled()) {
int clipRestoreCount = c.save();
c.clipRect(getGridClippingRect());
float[] positions = getTransformedPositions();
mGridPaint.setColor(mYAxis.getGridColor());
@ -150,6 +154,8 @@ public class YAxisRenderer extends AxisRenderer {
c.drawPath(linePath(gridLinePath, i, positions), mGridPaint);
gridLinePath.reset();
}
c.restoreToCount(clipRestoreCount);
}
if (mYAxis.isDrawZeroLineEnabled()) {
@ -157,6 +163,14 @@ public class YAxisRenderer extends AxisRenderer {
}
}
protected RectF mGridClippingRect = new RectF();
public RectF getGridClippingRect() {
mGridClippingRect.set(mViewPortHandler.getContentRect());
mGridClippingRect.inset(0.f, -mAxis.getGridLineWidth() / 2.f);
return mGridClippingRect;
}
/**
* Calculates the path for a grid line.
*
@ -220,6 +234,7 @@ public class YAxisRenderer extends AxisRenderer {
protected Path mRenderLimitLines = new Path();
protected float[] mRenderLimitLinesBuffer = new float[2];
protected RectF mLimitLineClippingRect = new RectF();
/**
* Draws the LimitLines associated with this axis to the screen.
*
@ -246,6 +261,11 @@ public class YAxisRenderer extends AxisRenderer {
if (!l.isEnabled())
continue;
int clipRestoreCount = c.save();
mLimitLineClippingRect.set(mViewPortHandler.getContentRect());
mLimitLineClippingRect.inset(0.f, -l.getLineWidth() / 2.f);
c.clipRect(mLimitLineClippingRect);
mLimitLinePaint.setStyle(Paint.Style.STROKE);
mLimitLinePaint.setColor(l.getLineColor());
mLimitLinePaint.setStrokeWidth(l.getLineWidth());
@ -309,6 +329,8 @@ public class YAxisRenderer extends AxisRenderer {
pts[1] + yOffset, mLimitLinePaint);
}
}
c.restoreToCount(clipRestoreCount);
}
}
}

View file

@ -5,6 +5,7 @@ import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Path;
import android.graphics.RectF;
import com.github.mikephil.charting.components.LimitLine;
import com.github.mikephil.charting.components.YAxis;
@ -164,6 +165,13 @@ public class YAxisRendererHorizontalBarChart extends YAxisRenderer {
return positions;
}
@Override
public RectF getGridClippingRect() {
mGridClippingRect.set(mViewPortHandler.getContentRect());
mGridClippingRect.inset(-mAxis.getGridLineWidth() / 2.f, 0.f);
return mGridClippingRect;
}
@Override
protected Path linePath(Path p, int i, float[] positions) {
@ -225,6 +233,11 @@ public class YAxisRendererHorizontalBarChart extends YAxisRenderer {
if (!l.isEnabled())
continue;
int clipRestoreCount = c.save();
mLimitLineClippingRect.set(mViewPortHandler.getContentRect());
mLimitLineClippingRect.inset(-l.getLineWidth() / 2.f, 0.f);
c.clipRect(mLimitLineClippingRect);
pts[0] = l.getLimit();
pts[2] = l.getLimit();
@ -281,6 +294,8 @@ public class YAxisRendererHorizontalBarChart extends YAxisRenderer {
c.drawText(label, pts[0] - xOffset, mViewPortHandler.contentBottom() - yOffset, mLimitLinePaint);
}
}
c.restoreToCount(clipRestoreCount);
}
}
}