Fixes related to legend rendering (issue #1969)
This commit is contained in:
parent
eb44a13434
commit
9ccf58feab
5 changed files with 159 additions and 252 deletions
|
@ -52,12 +52,9 @@ public class PieChartActivity extends DemoBase implements OnSeekBarChangeListene
|
|||
|
||||
mSeekBarX = (SeekBar) findViewById(R.id.seekBar1);
|
||||
mSeekBarY = (SeekBar) findViewById(R.id.seekBar2);
|
||||
|
||||
mSeekBarX.setProgress(4);
|
||||
mSeekBarY.setProgress(10);
|
||||
|
||||
mSeekBarX.setOnSeekBarChangeListener(this);
|
||||
mSeekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
mChart = (PieChart) findViewById(R.id.chart1);
|
||||
mChart.setUsePercentValues(true);
|
||||
mChart.setDescription("");
|
||||
|
@ -95,6 +92,9 @@ public class PieChartActivity extends DemoBase implements OnSeekBarChangeListene
|
|||
mChart.animateY(1400, Easing.EasingOption.EaseInOutQuad);
|
||||
// mChart.spin(2000, 0, 360);
|
||||
|
||||
mSeekBarX.setOnSeekBarChangeListener(this);
|
||||
mSeekBarY.setOnSeekBarChangeListener(this);
|
||||
|
||||
Legend l = mChart.getLegend();
|
||||
l.setPosition(LegendPosition.RIGHT_OF_CHART);
|
||||
l.setXEntrySpace(7f);
|
||||
|
|
|
@ -74,6 +74,7 @@ public class ScatterChartActivity extends DemoBase implements OnSeekBarChangeLis
|
|||
Legend l = mChart.getLegend();
|
||||
l.setPosition(LegendPosition.RIGHT_OF_CHART);
|
||||
l.setTypeface(mTfLight);
|
||||
l.setXOffset(5f);
|
||||
|
||||
YAxis yl = mChart.getAxisLeft();
|
||||
yl.setTypeface(mTfLight);
|
||||
|
|
|
@ -15,13 +15,14 @@ import java.util.List;
|
|||
* Class representing the legend of the chart. The legend will contain one entry
|
||||
* per color and DataSet. Multiple colors in one DataSet are grouped together.
|
||||
* The legend object is NOT available before setting data to the chart.
|
||||
*
|
||||
*
|
||||
* @author Philipp Jahoda
|
||||
*/
|
||||
public class Legend extends ComponentBase {
|
||||
|
||||
/**
|
||||
* This property is deprecated - Use `position`, `horizontalAlignment`, `verticalAlignment`, `orientation`, `drawInside`, `direction`.
|
||||
* This property is deprecated - Use `position`, `horizontalAlignment`, `verticalAlignment`, `orientation`, `drawInside`,
|
||||
* `direction`.
|
||||
*/
|
||||
public enum LegendPosition {
|
||||
RIGHT_OF_CHART, RIGHT_OF_CHART_CENTER, RIGHT_OF_CHART_INSIDE,
|
||||
|
@ -35,18 +36,15 @@ public class Legend extends ComponentBase {
|
|||
SQUARE, CIRCLE, LINE
|
||||
}
|
||||
|
||||
public enum LegendHorizontalAlignment
|
||||
{
|
||||
public enum LegendHorizontalAlignment {
|
||||
LEFT, CENTER, RIGHT
|
||||
}
|
||||
|
||||
public enum LegendVerticalAlignment
|
||||
{
|
||||
public enum LegendVerticalAlignment {
|
||||
TOP, CENTER, BOTTOM
|
||||
}
|
||||
|
||||
public enum LegendOrientation
|
||||
{
|
||||
public enum LegendOrientation {
|
||||
HORIZONTAL, VERTICAL
|
||||
}
|
||||
|
||||
|
@ -60,7 +58,9 @@ public class Legend extends ComponentBase {
|
|||
*/
|
||||
private int[] mColors;
|
||||
|
||||
/** the legend text array. a null label will start a group. */
|
||||
/**
|
||||
* the legend text array. a null label will start a group.
|
||||
*/
|
||||
private String[] mLabels;
|
||||
|
||||
/**
|
||||
|
@ -86,13 +86,19 @@ public class Legend extends ComponentBase {
|
|||
private LegendOrientation mOrientation = LegendOrientation.HORIZONTAL;
|
||||
private boolean mDrawInside = false;
|
||||
|
||||
/** the text direction for the legend */
|
||||
/**
|
||||
* the text direction for the legend
|
||||
*/
|
||||
private LegendDirection mDirection = LegendDirection.LEFT_TO_RIGHT;
|
||||
|
||||
/** the shape/form the legend colors are drawn in */
|
||||
/**
|
||||
* the shape/form the legend colors are drawn in
|
||||
*/
|
||||
private LegendForm mShape = LegendForm.SQUARE;
|
||||
|
||||
/** the size of the legend forms/shapes */
|
||||
/**
|
||||
* the size of the legend forms/shapes
|
||||
*/
|
||||
private float mFormSize = 8f;
|
||||
|
||||
/**
|
||||
|
@ -112,13 +118,19 @@ public class Legend extends ComponentBase {
|
|||
*/
|
||||
private float mFormToTextSpace = 5f;
|
||||
|
||||
/** the space that should be left between stacked forms */
|
||||
/**
|
||||
* the space that should be left between stacked forms
|
||||
*/
|
||||
private float mStackSpace = 3f;
|
||||
|
||||
/** the maximum relative size out of the whole chart view in percent */
|
||||
/**
|
||||
* the maximum relative size out of the whole chart view in percent
|
||||
*/
|
||||
private float mMaxSizePercent = 0.95f;
|
||||
|
||||
/** default constructor */
|
||||
/**
|
||||
* default constructor
|
||||
*/
|
||||
public Legend() {
|
||||
|
||||
mFormSize = Utils.convertDpToPixel(8f);
|
||||
|
@ -133,7 +145,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* Constructor. Provide colors and labels for the legend.
|
||||
*
|
||||
*
|
||||
* @param colors
|
||||
* @param labels
|
||||
*/
|
||||
|
@ -155,7 +167,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* Constructor. Provide colors and labels for the legend.
|
||||
*
|
||||
*
|
||||
* @param colors
|
||||
* @param labels
|
||||
*/
|
||||
|
@ -171,30 +183,32 @@ public class Legend extends ComponentBase {
|
|||
"colors array and labels array need to be of same size");
|
||||
}
|
||||
|
||||
this.setComputedColors(colors);
|
||||
this.setComputedLabels(labels);
|
||||
this.mColors = Utils.convertIntegers(colors);
|
||||
this.mLabels = Utils.convertStrings(labels);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method sets the automatically computed colors for the legend. Use setCustom(...) to set custom colors.
|
||||
*
|
||||
* @param colors
|
||||
*/
|
||||
public void setComputedColors(List<Integer> colors) {
|
||||
if(mColors != null && colors.size() == mColors.length){
|
||||
if (mColors != null && colors.size() == mColors.length) {
|
||||
Utils.copyIntegers(colors, mColors);
|
||||
}else {
|
||||
} else {
|
||||
mColors = Utils.convertIntegers(colors);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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()){
|
||||
if (mLabels != null && mLabels.length == labels.size()) {
|
||||
Utils.copyStrings(labels, mLabels);
|
||||
}else {
|
||||
} else {
|
||||
mLabels = Utils.convertStrings(labels);
|
||||
}
|
||||
}
|
||||
|
@ -202,7 +216,7 @@ public class Legend extends ComponentBase {
|
|||
/**
|
||||
* returns the maximum length in pixels across all legend labels + formsize
|
||||
* + formtotextspace
|
||||
*
|
||||
*
|
||||
* @param p the paint object used for rendering the text
|
||||
* @return
|
||||
*/
|
||||
|
@ -226,7 +240,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* returns the maximum height in pixels across all legend labels
|
||||
*
|
||||
*
|
||||
* @param p the paint object used for rendering the text
|
||||
* @return
|
||||
*/
|
||||
|
@ -250,7 +264,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* returns all the colors the legend uses
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public int[] getColors() {
|
||||
|
@ -259,7 +273,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* returns all the labels the legend uses
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String[] getLabels() {
|
||||
|
@ -268,7 +282,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* Returns the legend-label at the given index.
|
||||
*
|
||||
*
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
|
@ -299,15 +313,15 @@ public class Legend extends ComponentBase {
|
|||
* let the changes take effect)
|
||||
*/
|
||||
public void setExtra(List<Integer> colors, List<String> labels) {
|
||||
if(mExtraColors != null && mExtraColors.length == colors.size()){
|
||||
if (mExtraColors != null && mExtraColors.length == colors.size()) {
|
||||
Utils.copyIntegers(colors, mExtraColors);
|
||||
}else {
|
||||
} else {
|
||||
this.mExtraColors = Utils.convertIntegers(colors);
|
||||
}
|
||||
|
||||
if(mExtraLabels != null && mExtraLabels.length == labels.size()){
|
||||
if (mExtraLabels != null && mExtraLabels.length == labels.size()) {
|
||||
Utils.copyStrings(labels, mExtraLabels);
|
||||
}else {
|
||||
} else {
|
||||
this.mExtraLabels = Utils.convertStrings(labels);
|
||||
}
|
||||
}
|
||||
|
@ -360,8 +374,8 @@ public class Legend extends ComponentBase {
|
|||
"colors array and labels array need to be of same size");
|
||||
}
|
||||
|
||||
this.setComputedColors(colors);
|
||||
this.setComputedLabels(labels);
|
||||
mColors = Utils.convertIntegers(colors);
|
||||
mLabels = Utils.convertStrings(labels);
|
||||
mIsLegendCustom = true;
|
||||
}
|
||||
|
||||
|
@ -376,7 +390,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* @return true if a custom legend labels and colors has been set default
|
||||
* false (automatic legend)
|
||||
* false (automatic legend)
|
||||
*/
|
||||
public boolean isLegendCustom() {
|
||||
return mIsLegendCustom;
|
||||
|
@ -384,7 +398,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* returns the position of the legend relative to the chart
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public LegendPosition getPosition() {
|
||||
|
@ -393,8 +407,7 @@ public class Legend extends ComponentBase {
|
|||
&& mHorizontalAlignment == LegendHorizontalAlignment.CENTER
|
||||
&& mVerticalAlignment == LegendVerticalAlignment.CENTER) {
|
||||
return LegendPosition.PIECHART_CENTER;
|
||||
}
|
||||
else if (mOrientation == LegendOrientation.HORIZONTAL) {
|
||||
} else if (mOrientation == LegendOrientation.HORIZONTAL) {
|
||||
if (mVerticalAlignment == LegendVerticalAlignment.TOP)
|
||||
return mHorizontalAlignment == LegendHorizontalAlignment.LEFT
|
||||
? LegendPosition.ABOVE_CHART_LEFT
|
||||
|
@ -407,8 +420,7 @@ public class Legend extends ComponentBase {
|
|||
: (mHorizontalAlignment == LegendHorizontalAlignment.RIGHT
|
||||
? LegendPosition.BELOW_CHART_RIGHT
|
||||
: LegendPosition.BELOW_CHART_CENTER);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
if (mHorizontalAlignment == LegendHorizontalAlignment.LEFT)
|
||||
return mVerticalAlignment == LegendVerticalAlignment.TOP && mDrawInside
|
||||
? LegendPosition.LEFT_OF_CHART_INSIDE
|
||||
|
@ -426,7 +438,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* sets the position of the legend relative to the whole chart
|
||||
*
|
||||
*
|
||||
* @param newValue
|
||||
*/
|
||||
public void setPosition(LegendPosition newValue) {
|
||||
|
@ -579,7 +591,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* returns the current form/shape that is set for the legend
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public LegendForm getForm() {
|
||||
|
@ -588,7 +600,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* sets the form/shape of the legend forms
|
||||
*
|
||||
*
|
||||
* @param shape
|
||||
*/
|
||||
public void setForm(LegendForm shape) {
|
||||
|
@ -598,7 +610,7 @@ public class Legend extends ComponentBase {
|
|||
/**
|
||||
* sets the size in pixels of the legend forms, this is internally converted
|
||||
* in dp, default 8f
|
||||
*
|
||||
*
|
||||
* @param size
|
||||
*/
|
||||
public void setFormSize(float size) {
|
||||
|
@ -607,7 +619,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* returns the size in dp of the legend forms
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getFormSize() {
|
||||
|
@ -617,7 +629,7 @@ public class Legend extends ComponentBase {
|
|||
/**
|
||||
* returns the space between the legend entries on a horizontal axis in
|
||||
* pixels
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getXEntrySpace() {
|
||||
|
@ -627,7 +639,7 @@ public class Legend extends ComponentBase {
|
|||
/**
|
||||
* sets the space between the legend entries on a horizontal axis in pixels,
|
||||
* converts to dp internally
|
||||
*
|
||||
*
|
||||
* @param space
|
||||
*/
|
||||
public void setXEntrySpace(float space) {
|
||||
|
@ -636,7 +648,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* returns the space between the legend entries on a vertical axis in pixels
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getYEntrySpace() {
|
||||
|
@ -646,7 +658,7 @@ public class Legend extends ComponentBase {
|
|||
/**
|
||||
* sets the space between the legend entries on a vertical axis in pixels,
|
||||
* converts to dp internally
|
||||
*
|
||||
*
|
||||
* @param space
|
||||
*/
|
||||
public void setYEntrySpace(float space) {
|
||||
|
@ -655,7 +667,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* returns the space between the form and the actual label/text
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getFormToTextSpace() {
|
||||
|
@ -665,7 +677,7 @@ public class Legend extends ComponentBase {
|
|||
/**
|
||||
* sets the space between the form and the actual label/text, converts to dp
|
||||
* internally
|
||||
*
|
||||
*
|
||||
* @param space
|
||||
*/
|
||||
public void setFormToTextSpace(float space) {
|
||||
|
@ -674,7 +686,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* returns the space that is left out between stacked forms (with no label)
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getStackSpace() {
|
||||
|
@ -683,7 +695,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
/**
|
||||
* sets the space that is left out between stacked forms (with no label)
|
||||
*
|
||||
*
|
||||
* @param space
|
||||
*/
|
||||
public void setStackSpace(float space) {
|
||||
|
@ -691,73 +703,22 @@ public class Legend extends ComponentBase {
|
|||
}
|
||||
|
||||
/**
|
||||
* calculates the full width the fully drawn legend will use in pixels
|
||||
*
|
||||
* @return
|
||||
* the total width of the legend (needed width space)
|
||||
*/
|
||||
public float getFullWidth(Paint labelpaint) {
|
||||
|
||||
float width = 0f;
|
||||
|
||||
for (int i = 0; i < mLabels.length; i++) {
|
||||
|
||||
// grouped forms have null labels
|
||||
if (mLabels[i] != null) {
|
||||
|
||||
// make a step to the left
|
||||
if (mColors[i] != ColorTemplate.COLOR_SKIP)
|
||||
width += mFormSize + mFormToTextSpace;
|
||||
|
||||
width += Utils.calcTextWidth(labelpaint, mLabels[i]);
|
||||
|
||||
if (i < mLabels.length - 1)
|
||||
width += mXEntrySpace;
|
||||
} else {
|
||||
width += mFormSize;
|
||||
if (i < mLabels.length - 1)
|
||||
width += mStackSpace;
|
||||
}
|
||||
}
|
||||
|
||||
return width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the full height of the drawn legend.
|
||||
*
|
||||
* @param labelpaint
|
||||
* @return
|
||||
*/
|
||||
public float getFullHeight(Paint labelpaint) {
|
||||
|
||||
float height = 0f;
|
||||
|
||||
for (int i = 0; i < mLabels.length; i++) {
|
||||
|
||||
// grouped forms have null labels
|
||||
if (mLabels[i] != null) {
|
||||
|
||||
height += Utils.calcTextHeight(labelpaint, mLabels[i]);
|
||||
|
||||
if (i < mLabels.length - 1)
|
||||
height += mYEntrySpace;
|
||||
}
|
||||
}
|
||||
|
||||
return height;
|
||||
}
|
||||
|
||||
/** the total width of the legend (needed width space) */
|
||||
public float mNeededWidth = 0f;
|
||||
|
||||
/** the total height of the legend (needed height space) */
|
||||
/**
|
||||
* the total height of the legend (needed height space)
|
||||
*/
|
||||
public float mNeededHeight = 0f;
|
||||
|
||||
public float mTextHeightMax = 0f;
|
||||
|
||||
public float mTextWidthMax = 0f;
|
||||
|
||||
/** flag that indicates if word wrapping is enabled */
|
||||
/**
|
||||
* flag that indicates if word wrapping is enabled
|
||||
*/
|
||||
private boolean mWordWrapEnabled = false;
|
||||
|
||||
/**
|
||||
|
@ -766,7 +727,7 @@ public class Legend extends ComponentBase {
|
|||
* wrapping a legend takes a toll on performance. / you may want to set
|
||||
* maxSizePercent when word wrapping, to set the point where the text wraps.
|
||||
* / default: false
|
||||
*
|
||||
*
|
||||
* @param enabled
|
||||
*/
|
||||
public void setWordWrapEnabled(boolean enabled) {
|
||||
|
@ -776,7 +737,7 @@ public class Legend extends ComponentBase {
|
|||
/**
|
||||
* If this is set, then word wrapping the legend is enabled. This means the
|
||||
* legend will not be cut off if too long.
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public boolean isWordWrapEnabled() {
|
||||
|
@ -790,7 +751,7 @@ public class Legend extends ComponentBase {
|
|||
* affects the height of the legend. / If the legend is the center of the
|
||||
* piechart, then this defines the size of the rectangular bounds out of the
|
||||
* size of the "hole". / default: 0.95f (95%)
|
||||
*
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public float getMaxSizePercent() {
|
||||
|
@ -802,45 +763,34 @@ public class Legend extends ComponentBase {
|
|||
* the legend is to the right/left of the chart, then this affects the width
|
||||
* of the legend. / If the legend is to the top/bottom of the chart, then
|
||||
* this affects the height of the legend. / default: 0.95f (95%)
|
||||
*
|
||||
*
|
||||
* @param maxSize
|
||||
*/
|
||||
public void setMaxSizePercent(float maxSize) {
|
||||
mMaxSizePercent = maxSize;
|
||||
}
|
||||
private boolean isCalculatedLineSizesArrayListResized = true;
|
||||
|
||||
private FSize[] mCalculatedLabelSizes = new FSize[] {};
|
||||
private Boolean[] mCalculatedLabelBreakPoints = new Boolean[] {};
|
||||
private FSize[] mCalculatedLineSizes = new FSize[] {};
|
||||
private List<FSize> mCalculatedLabelSizes = new ArrayList<>(16);
|
||||
private List<Boolean> mCalculatedLabelBreakPoints = new ArrayList<>(16);
|
||||
private List<FSize> mCalculatedLineSizes = new ArrayList<>(16);
|
||||
|
||||
public FSize[] getCalculatedLabelSizes() {
|
||||
public List<FSize> getCalculatedLabelSizes() {
|
||||
return mCalculatedLabelSizes;
|
||||
}
|
||||
|
||||
public Boolean[] getCalculatedLabelBreakPoints() {
|
||||
public List<Boolean> getCalculatedLabelBreakPoints() {
|
||||
return mCalculatedLabelBreakPoints;
|
||||
}
|
||||
|
||||
public FSize[] getCalculatedLineSizes() {
|
||||
if(mCalculatedLineSizes == null || isCalculatedLineSizesArrayListResized){
|
||||
|
||||
mCalculatedLineSizes = calculatedLineSizesForCalculateDimensions
|
||||
.toArray(new FSize[calculatedLineSizesForCalculateDimensions.size()]);
|
||||
|
||||
isCalculatedLineSizesArrayListResized = false;
|
||||
|
||||
}
|
||||
public List<FSize> getCalculatedLineSizes() {
|
||||
return mCalculatedLineSizes;
|
||||
}
|
||||
|
||||
protected Paint.FontMetrics fontMetricsForCalculateDimensions = new Paint.FontMetrics();
|
||||
protected ArrayList<FSize> calculatedLineSizesForCalculateDimensions = new ArrayList<>();
|
||||
/**
|
||||
* Calculates the dimensions of the Legend. This includes the maximum width
|
||||
* and height of a single entry, as well as the total width and height of
|
||||
* the Legend.
|
||||
*
|
||||
*
|
||||
* @param labelpaint
|
||||
*/
|
||||
public void calculateDimensions(Paint labelpaint, ViewPortHandler viewPortHandler) {
|
||||
|
@ -852,7 +802,7 @@ public class Legend extends ComponentBase {
|
|||
case VERTICAL: {
|
||||
|
||||
float maxWidth = 0f, maxHeight = 0f, width = 0f;
|
||||
float labelLineHeight = Utils.getLineHeight(labelpaint, fontMetricsForCalculateDimensions);
|
||||
float labelLineHeight = Utils.getLineHeight(labelpaint);
|
||||
final int count = mLabels.length;
|
||||
boolean wasStacked = false;
|
||||
|
||||
|
@ -886,8 +836,7 @@ public class Legend extends ComponentBase {
|
|||
|
||||
if (i < count - 1)
|
||||
maxHeight += labelLineHeight + mYEntrySpace;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
wasStacked = true;
|
||||
width += mFormSize;
|
||||
if (i < count - 1)
|
||||
|
@ -905,81 +854,44 @@ public class Legend extends ComponentBase {
|
|||
case HORIZONTAL: {
|
||||
|
||||
int labelCount = mLabels.length;
|
||||
float labelLineHeight = Utils.getLineHeight(labelpaint, fontMetricsForCalculateDimensions);
|
||||
float labelLineSpacing = Utils.getLineSpacing(labelpaint, fontMetricsForCalculateDimensions) + mYEntrySpace;
|
||||
float labelLineHeight = Utils.getLineHeight(labelpaint);
|
||||
float labelLineSpacing = Utils.getLineSpacing(labelpaint) + mYEntrySpace;
|
||||
float contentWidth = viewPortHandler.contentWidth() * mMaxSizePercent;
|
||||
|
||||
// Prepare arrays for calculated layout
|
||||
|
||||
//ArrayList<Boolean> calculatedLabelBreakPoints = new ArrayList<Boolean>(labelCount);
|
||||
|
||||
if(mCalculatedLabelSizes.length != labelCount){
|
||||
FSize[] temp = new FSize[labelCount];
|
||||
int count = mCalculatedLabelSizes.length;
|
||||
for(int i = 0 ; i < count && i < labelCount ; i++){
|
||||
temp[i] = mCalculatedLabelSizes[i];
|
||||
}
|
||||
while(count > labelCount){
|
||||
count--;
|
||||
FSize.recycleInstance(mCalculatedLabelSizes[count]);
|
||||
}
|
||||
mCalculatedLabelSizes = temp;
|
||||
}
|
||||
int calculatedLabelSizesIndex = 0;
|
||||
|
||||
if(mCalculatedLabelBreakPoints.length != labelCount){
|
||||
mCalculatedLabelBreakPoints = new Boolean[labelCount];
|
||||
}
|
||||
int calculatedLabelBreakIndex = 0;
|
||||
|
||||
ArrayList<FSize> calculatedLineSizes = calculatedLineSizesForCalculateDimensions;
|
||||
FSize.recycleInstances(calculatedLineSizes);
|
||||
calculatedLineSizes.clear();
|
||||
|
||||
// Start calculating layout
|
||||
float maxLineWidth = 0.f;
|
||||
float currentLineWidth = 0.f;
|
||||
float requiredWidth = 0.f;
|
||||
int stackedStartIndex = -1;
|
||||
|
||||
mCalculatedLabelBreakPoints.clear();
|
||||
mCalculatedLabelSizes.clear();
|
||||
mCalculatedLineSizes.clear();
|
||||
|
||||
for (int i = 0; i < labelCount; i++) {
|
||||
|
||||
boolean drawingForm = mColors[i] != ColorTemplate.COLOR_SKIP;
|
||||
|
||||
mCalculatedLabelBreakPoints[calculatedLabelBreakIndex] = false;
|
||||
calculatedLabelBreakIndex++;
|
||||
mCalculatedLabelBreakPoints.add(false);
|
||||
|
||||
if (stackedStartIndex == -1) {
|
||||
// we are not stacking, so required width is for this label
|
||||
// only
|
||||
requiredWidth = 0.f;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
// add the spacing appropriate for stacked labels/forms
|
||||
requiredWidth += mStackSpace;
|
||||
}
|
||||
|
||||
// grouped forms have null labels
|
||||
if (mLabels[i] != null) {
|
||||
if(mCalculatedLabelSizes[calculatedLabelSizesIndex] == null){
|
||||
mCalculatedLabelSizes[calculatedLabelSizesIndex] = Utils.calcTextSize(labelpaint, mLabels[i]);
|
||||
}else{
|
||||
Utils.calcTextSize(labelpaint, mLabels[i], mCalculatedLabelSizes[calculatedLabelSizesIndex]);
|
||||
}
|
||||
FSize labelSize = mCalculatedLabelSizes[calculatedLabelSizesIndex];
|
||||
calculatedLabelSizesIndex++;
|
||||
requiredWidth += drawingForm ? mFormToTextSpace + mFormSize : 0.f;
|
||||
requiredWidth += labelSize.width;
|
||||
}
|
||||
else {
|
||||
|
||||
if(mCalculatedLabelSizes[calculatedLabelSizesIndex] == null){
|
||||
mCalculatedLabelSizes[calculatedLabelSizesIndex] = FSize.getInstance(0.f, 0.f);
|
||||
}else{
|
||||
mCalculatedLabelSizes[calculatedLabelSizesIndex].width = 0.f;
|
||||
mCalculatedLabelSizes[calculatedLabelSizesIndex].height = 0.f;
|
||||
}
|
||||
calculatedLabelSizesIndex++;
|
||||
mCalculatedLabelSizes.add(Utils.calcTextSize(labelpaint, mLabels[i]));
|
||||
requiredWidth += drawingForm ? mFormToTextSpace + mFormSize : 0.f;
|
||||
requiredWidth += mCalculatedLabelSizes.get(i).width;
|
||||
} else {
|
||||
|
||||
mCalculatedLabelSizes.add(FSize.getInstance(0.f, 0.f));
|
||||
requiredWidth += drawingForm ? mFormSize : 0.f;
|
||||
|
||||
if (stackedStartIndex == -1) {
|
||||
|
@ -1000,23 +912,22 @@ public class Legend extends ComponentBase {
|
|||
requiredSpacing + requiredWidth)) {
|
||||
// Expand current line
|
||||
currentLineWidth += requiredSpacing + requiredWidth;
|
||||
}
|
||||
else { // It doesn't fit, we need to wrap a line
|
||||
} else { // It doesn't fit, we need to wrap a line
|
||||
|
||||
// Add current line size to array
|
||||
calculatedLineSizes.add(FSize.getInstance(currentLineWidth, labelLineHeight));
|
||||
mCalculatedLineSizes.add(FSize.getInstance(currentLineWidth, labelLineHeight));
|
||||
maxLineWidth = Math.max(maxLineWidth, currentLineWidth);
|
||||
|
||||
// Start a new line
|
||||
mCalculatedLabelBreakPoints[
|
||||
mCalculatedLabelBreakPoints.set(
|
||||
stackedStartIndex > -1 ? stackedStartIndex
|
||||
: i] = true;
|
||||
: i, true);
|
||||
currentLineWidth = requiredWidth;
|
||||
}
|
||||
|
||||
if (i == labelCount - 1) {
|
||||
// Add last line size to array
|
||||
calculatedLineSizes.add(FSize.getInstance(currentLineWidth, labelLineHeight));
|
||||
mCalculatedLineSizes.add(FSize.getInstance(currentLineWidth, labelLineHeight));
|
||||
maxLineWidth = Math.max(maxLineWidth, currentLineWidth);
|
||||
}
|
||||
}
|
||||
|
@ -1024,24 +935,19 @@ public class Legend extends ComponentBase {
|
|||
stackedStartIndex = mLabels[i] != null ? -1 : stackedStartIndex;
|
||||
}
|
||||
|
||||
if(calculatedLineSizes.size() != mCalculatedLineSizes.length) {
|
||||
isCalculatedLineSizesArrayListResized = true;
|
||||
}else{
|
||||
for(int i = 0 ; i < mCalculatedLineSizes.length ; i++){
|
||||
mCalculatedLineSizes[i] = calculatedLineSizes.get(i);
|
||||
}
|
||||
}
|
||||
|
||||
mNeededWidth = maxLineWidth;
|
||||
mNeededHeight = labelLineHeight
|
||||
* (float) (mCalculatedLineSizes.length)
|
||||
* (float) (mCalculatedLineSizes.size())
|
||||
+ labelLineSpacing *
|
||||
(float) (mCalculatedLineSizes.length == 0
|
||||
(float) (mCalculatedLineSizes.size() == 0
|
||||
? 0
|
||||
: (mCalculatedLineSizes.length - 1));
|
||||
: (mCalculatedLineSizes.size() - 1));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mNeededHeight += mYOffset;
|
||||
mNeededWidth += mXOffset;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -70,8 +70,10 @@ public class LegendRenderer extends Renderer {
|
|||
return mLegendFormPaint;
|
||||
}
|
||||
|
||||
protected ArrayList<String> labelsForComputeLegend = new ArrayList<>(16);
|
||||
protected ArrayList<Integer> colorsForComputeLegend = new ArrayList<>(16);
|
||||
|
||||
protected List<String> computedLabels = new ArrayList<>(16);
|
||||
protected List<Integer> computedColors = new ArrayList<>(16);
|
||||
|
||||
/**
|
||||
* Prepares the legend and calculates all needed forms, labels and colors.
|
||||
*
|
||||
|
@ -81,11 +83,8 @@ public class LegendRenderer extends Renderer {
|
|||
|
||||
if (!mLegend.isLegendCustom()) {
|
||||
|
||||
ArrayList<String> labels = labelsForComputeLegend;
|
||||
ArrayList<Integer> colors = colorsForComputeLegend;
|
||||
|
||||
labels.clear();
|
||||
colors.clear();
|
||||
computedLabels.clear();
|
||||
computedColors.clear();
|
||||
|
||||
// loop for building up the colors and labels used in the legend
|
||||
for (int i = 0; i < data.getDataSetCount(); i++) {
|
||||
|
@ -103,14 +102,14 @@ public class LegendRenderer extends Renderer {
|
|||
|
||||
for (int j = 0; j < clrs.size() && j < bds.getStackSize(); j++) {
|
||||
|
||||
labels.add(sLabels[j % sLabels.length]);
|
||||
colors.add(clrs.get(j));
|
||||
computedLabels.add(sLabels[j % sLabels.length]);
|
||||
computedColors.add(clrs.get(j));
|
||||
}
|
||||
|
||||
if (bds.getLabel() != null) {
|
||||
// add the legend description label
|
||||
colors.add(ColorTemplate.COLOR_SKIP);
|
||||
labels.add(bds.getLabel());
|
||||
computedColors.add(ColorTemplate.COLOR_SKIP);
|
||||
computedLabels.add(bds.getLabel());
|
||||
}
|
||||
|
||||
} else if (dataSet instanceof IPieDataSet) {
|
||||
|
@ -119,27 +118,27 @@ public class LegendRenderer extends Renderer {
|
|||
|
||||
for (int j = 0; j < clrs.size() && j < entryCount; j++) {
|
||||
|
||||
labels.add(pds.getEntryForIndex(j).getLabel());
|
||||
colors.add(clrs.get(j));
|
||||
computedLabels.add(pds.getEntryForIndex(j).getLabel());
|
||||
computedColors.add(clrs.get(j));
|
||||
}
|
||||
|
||||
if (pds.getLabel() != null) {
|
||||
// add the legend description label
|
||||
colors.add(ColorTemplate.COLOR_SKIP);
|
||||
labels.add(pds.getLabel());
|
||||
computedColors.add(ColorTemplate.COLOR_SKIP);
|
||||
computedLabels.add(pds.getLabel());
|
||||
}
|
||||
|
||||
} else if (dataSet instanceof ICandleDataSet && ((ICandleDataSet) dataSet).getDecreasingColor() !=
|
||||
ColorTemplate.COLOR_NONE) {
|
||||
|
||||
int decreasingColor = ((ICandleDataSet) dataSet).getDecreasingColor();
|
||||
colors.add(decreasingColor);
|
||||
computedColors.add(decreasingColor);
|
||||
|
||||
int increasingColor = ((ICandleDataSet) dataSet).getIncreasingColor();
|
||||
colors.add(increasingColor);
|
||||
computedColors.add(increasingColor);
|
||||
|
||||
labels.add(null);
|
||||
labels.add(dataSet.getLabel());
|
||||
computedLabels.add(null);
|
||||
computedLabels.add(dataSet.getLabel());
|
||||
|
||||
} else { // all others
|
||||
|
||||
|
@ -148,26 +147,26 @@ public class LegendRenderer extends Renderer {
|
|||
// if multiple colors are set for a DataSet, group them
|
||||
if (j < clrs.size() - 1 && j < entryCount - 1) {
|
||||
|
||||
labels.add(null);
|
||||
computedLabels.add(null);
|
||||
} else { // add label to the last entry
|
||||
|
||||
String label = data.getDataSetByIndex(i).getLabel();
|
||||
labels.add(label);
|
||||
computedLabels.add(label);
|
||||
}
|
||||
|
||||
colors.add(clrs.get(j));
|
||||
computedColors.add(clrs.get(j));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mLegend.getExtraColors() != null && mLegend.getExtraLabels() != null) {
|
||||
for (int color : mLegend.getExtraColors())
|
||||
colors.add(color);
|
||||
Collections.addAll(labels, mLegend.getExtraLabels());
|
||||
computedColors.add(color);
|
||||
Collections.addAll(computedLabels, mLegend.getExtraLabels());
|
||||
}
|
||||
|
||||
mLegend.setComputedColors(colors);
|
||||
mLegend.setComputedLabels(labels);
|
||||
mLegend.setComputedColors(computedColors);
|
||||
mLegend.setComputedLabels(computedLabels);
|
||||
}
|
||||
|
||||
Typeface tf = mLegend.getTypeface();
|
||||
|
@ -182,7 +181,8 @@ public class LegendRenderer extends Renderer {
|
|||
mLegend.calculateDimensions(mLegendLabelPaint, mViewPortHandler);
|
||||
}
|
||||
|
||||
protected Paint.FontMetrics fontMetricsForRenderLegent = new Paint.FontMetrics();
|
||||
protected Paint.FontMetrics legendFontMetrics = new Paint.FontMetrics();
|
||||
|
||||
public void renderLegend(Canvas c) {
|
||||
|
||||
if (!mLegend.isEnabled())
|
||||
|
@ -196,8 +196,8 @@ public class LegendRenderer extends Renderer {
|
|||
mLegendLabelPaint.setTextSize(mLegend.getTextSize());
|
||||
mLegendLabelPaint.setColor(mLegend.getTextColor());
|
||||
|
||||
float labelLineHeight = Utils.getLineHeight(mLegendLabelPaint, fontMetricsForRenderLegent);
|
||||
float labelLineSpacing = Utils.getLineSpacing(mLegendLabelPaint, fontMetricsForRenderLegent) + mLegend.getYEntrySpace();
|
||||
float labelLineHeight = Utils.getLineHeight(mLegendLabelPaint, legendFontMetrics);
|
||||
float labelLineSpacing = Utils.getLineSpacing(mLegendLabelPaint, legendFontMetrics) + mLegend.getYEntrySpace();
|
||||
float formYOffset = labelLineHeight - Utils.calcTextHeight(mLegendLabelPaint, "ABC") / 2.f;
|
||||
|
||||
String[] labels = mLegend.getLabels();
|
||||
|
@ -269,11 +269,11 @@ public class LegendRenderer extends Renderer {
|
|||
switch (orientation) {
|
||||
case HORIZONTAL: {
|
||||
|
||||
FSize[] calculatedLineSizes = mLegend.getCalculatedLineSizes();
|
||||
FSize[] calculatedLabelSizes = mLegend.getCalculatedLabelSizes();
|
||||
Boolean[] calculatedLabelBreakPoints = mLegend.getCalculatedLabelBreakPoints();
|
||||
List<FSize> calculatedLineSizes = mLegend.getCalculatedLineSizes();
|
||||
List<FSize> calculatedLabelSizes = mLegend.getCalculatedLabelSizes();
|
||||
List<Boolean> calculatedLabelBreakPoints = mLegend.getCalculatedLabelBreakPoints();
|
||||
|
||||
float posX = originPosX;
|
||||
float posX = originPosX + xoffset;
|
||||
float posY = 0.f;
|
||||
|
||||
switch (verticalAlignment) {
|
||||
|
@ -293,17 +293,17 @@ public class LegendRenderer extends Renderer {
|
|||
int lineIndex = 0;
|
||||
|
||||
for (int i = 0, count = labels.length; i < count; i++) {
|
||||
if (i < calculatedLabelBreakPoints.length && calculatedLabelBreakPoints[i]) {
|
||||
if (i < calculatedLabelBreakPoints.size() && calculatedLabelBreakPoints.get(i)) {
|
||||
posX = originPosX;
|
||||
posY += labelLineHeight + labelLineSpacing;
|
||||
}
|
||||
|
||||
if (posX == originPosX &&
|
||||
horizontalAlignment == Legend.LegendHorizontalAlignment.CENTER &&
|
||||
lineIndex < calculatedLineSizes.length) {
|
||||
lineIndex < calculatedLineSizes.size()) {
|
||||
posX += (direction == Legend.LegendDirection.RIGHT_TO_LEFT
|
||||
? calculatedLineSizes[lineIndex].width
|
||||
: -calculatedLineSizes[lineIndex].width) / 2.f;
|
||||
? calculatedLineSizes.get(lineIndex).width
|
||||
: -calculatedLineSizes.get(lineIndex).width) / 2.f;
|
||||
lineIndex++;
|
||||
}
|
||||
|
||||
|
@ -326,12 +326,12 @@ public class LegendRenderer extends Renderer {
|
|||
formToTextSpace;
|
||||
|
||||
if (direction == Legend.LegendDirection.RIGHT_TO_LEFT)
|
||||
posX -= calculatedLabelSizes[i].width;
|
||||
posX -= calculatedLabelSizes.get(i).width;
|
||||
|
||||
drawLabel(c, posX, posY + labelLineHeight, labels[i]);
|
||||
|
||||
if (direction == Legend.LegendDirection.LEFT_TO_RIGHT)
|
||||
posX += calculatedLabelSizes[i].width;
|
||||
posX += calculatedLabelSizes.get(i).width;
|
||||
|
||||
posX += direction == Legend.LegendDirection.RIGHT_TO_LEFT ? -xEntrySpace : xEntrySpace;
|
||||
} else
|
||||
|
@ -372,7 +372,7 @@ public class LegendRenderer extends Renderer {
|
|||
for (int i = 0; i < labels.length; i++) {
|
||||
|
||||
Boolean drawingForm = colors[i] != ColorTemplate.COLOR_SKIP;
|
||||
float posX = originPosX;
|
||||
float posX = originPosX + xoffset;
|
||||
|
||||
if (drawingForm) {
|
||||
if (direction == Legend.LegendDirection.LEFT_TO_RIGHT)
|
||||
|
|
|
@ -163,9 +163,10 @@ public abstract class Utils {
|
|||
return r.height();
|
||||
}
|
||||
|
||||
private static Paint.FontMetrics mFontMetrics = new Paint.FontMetrics();
|
||||
|
||||
public static float getLineHeight(Paint paint) {
|
||||
Paint.FontMetrics metrics = new Paint.FontMetrics();
|
||||
return getLineHeight(paint, metrics);
|
||||
return getLineHeight(paint, mFontMetrics);
|
||||
}
|
||||
|
||||
public static float getLineHeight(Paint paint, Paint.FontMetrics fontMetrics){
|
||||
|
@ -174,8 +175,7 @@ public abstract class Utils {
|
|||
}
|
||||
|
||||
public static float getLineSpacing(Paint paint) {
|
||||
Paint.FontMetrics metrics = new Paint.FontMetrics();
|
||||
return getLineSpacing(paint, metrics);
|
||||
return getLineSpacing(paint, mFontMetrics);
|
||||
}
|
||||
|
||||
public static float getLineSpacing(Paint paint, Paint.FontMetrics fontMetrics){
|
||||
|
|
Loading…
Add table
Reference in a new issue