Skip to content

Commit b765b90

Browse files
committed
Merge pull request PhilJay#710 from danielgindi/master
Improvements to legend drawing
2 parents 9f51232 + f57b0a6 commit b765b90

3 files changed

Lines changed: 63 additions & 108 deletions

File tree

MPChartLib/src/com/github/mikephil/charting/components/Legend.java

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ public enum LegendDirection {
8282
/**
8383
* the space between the legend entries on a vertical axis, default 5f
8484
*/
85-
private float mYEntrySpace = 5f;
85+
private float mYEntrySpace = 0f;
8686

8787
/**
8888
* the space between the legend entries on a vertical axis, default 2f
@@ -102,7 +102,7 @@ public Legend() {
102102

103103
mFormSize = Utils.convertDpToPixel(8f);
104104
mXEntrySpace = Utils.convertDpToPixel(6f);
105-
mYEntrySpace = Utils.convertDpToPixel(5f);
105+
mYEntrySpace = Utils.convertDpToPixel(0f);
106106
mFormToTextSpace = Utils.convertDpToPixel(5f);
107107
mTextSize = Utils.convertDpToPixel(10f);
108108
mStackSpace = Utils.convertDpToPixel(3f);
@@ -680,7 +680,8 @@ public void calculateDimensions(Paint labelpaint, ViewPortHandler viewPortHandle
680680
|| mPosition == LegendPosition.BELOW_CHART_CENTER) {
681681

682682
int labelCount = mLabels.length;
683-
float labelLineHeight = -labelpaint.ascent() - labelpaint.descent();
683+
float labelLineHeight = Utils.getLineHeight(labelpaint);
684+
float labelLineSpacing = Utils.getLineSpacing(labelpaint) + mYEntrySpace;
684685
float contentWidth = viewPortHandler.contentWidth();
685686

686687
// Prepare arrays for calculated layout
@@ -763,8 +764,8 @@ public void calculateDimensions(Paint labelpaint, ViewPortHandler viewPortHandle
763764
stackedStartIndex = mLabels[i] != null ? -1 : stackedStartIndex;
764765
}
765766

766-
mCalculatedLabelSizes = calculatedLabelSizes.toArray(new FSize[calculatedLabelSizes
767-
.size()]);
767+
mCalculatedLabelSizes = calculatedLabelSizes.toArray(
768+
new FSize[calculatedLabelSizes.size()]);
768769
mCalculatedLabelBreakPoints = calculatedLabelBreakPoints
769770
.toArray(new Boolean[calculatedLabelBreakPoints.size()]);
770771
mCalculatedLineSizes = calculatedLineSizes
@@ -775,9 +776,9 @@ public void calculateDimensions(Paint labelpaint, ViewPortHandler viewPortHandle
775776
mNeededWidth = maxLineWidth;
776777
mNeededHeight = labelLineHeight
777778
* (float) (mCalculatedLineSizes.length)
778-
+
779-
mYEntrySpace
780-
* (float) (mCalculatedLineSizes.length == 0 ? 0
779+
+ labelLineSpacing *
780+
(float) (mCalculatedLineSizes.length == 0
781+
? 0
781782
: (mCalculatedLineSizes.length - 1));
782783

783784
} else {

MPChartLib/src/com/github/mikephil/charting/renderer/LegendRenderer.java

Lines changed: 44 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,9 @@ public void renderLegend(Canvas c) {
173173
mLegendLabelPaint.setTextSize(mLegend.getTextSize());
174174
mLegendLabelPaint.setColor(mLegend.getTextColor());
175175

176-
float labelLineHeight = mLegendLabelPaint.getFontMetrics().bottom - mLegendLabelPaint.getFontMetrics().top; //- mLegendLabelPaint.ascent() - mLegendLabelPaint.descent(); // Utils.calcTextHeight(mLegendLabelPaint, "AQJ");
176+
float labelLineHeight = Utils.getLineHeight(mLegendLabelPaint);
177+
float labelLineSpacing = Utils.getLineSpacing(mLegendLabelPaint) + mLegend.getYEntrySpace();
178+
float formYOffset = labelLineHeight - Utils.calcTextHeight(mLegendLabelPaint, "ABC") / 2.f;
177179

178180
String[] labels = mLegend.getLabels();
179181
int[] colors = mLegend.getColors();
@@ -186,10 +188,6 @@ public void renderLegend(Canvas c) {
186188
// space between the entries
187189
float stackSpace = mLegend.getStackSpace();
188190

189-
// the amount of pixels the text needs to be set down to be on the same
190-
// height as the form
191-
float textDrop = (Utils.calcTextHeight(mLegendLabelPaint, "AQJ") + formSize) / 2f;
192-
193191
float posX, posY;
194192

195193
float yoffset = mLegend.getYOffset();
@@ -234,7 +232,7 @@ else if (legendPosition == Legend.LegendPosition.BELOW_CHART_RIGHT) {
234232
for (int i = 0, count = labels.length; i < count; i++) {
235233
if (calculatedLabelBreakPoints[i]) {
236234
posX = originPosX;
237-
posY += labelLineHeight;
235+
posY += labelLineHeight + labelLineSpacing;
238236
}
239237

240238
if (posX == originPosX && legendPosition == Legend.LegendPosition.BELOW_CHART_CENTER) {
@@ -249,7 +247,7 @@ else if (legendPosition == Legend.LegendPosition.BELOW_CHART_RIGHT) {
249247
if (direction == Legend.LegendDirection.RIGHT_TO_LEFT)
250248
posX -= formSize;
251249

252-
drawForm(c, posX, posY + labelLineHeight / 2.f, i, mLegend);
250+
drawForm(c, posX, posY + formYOffset, i, mLegend);
253251

254252
if (direction == Legend.LegendDirection.LEFT_TO_RIGHT)
255253
posX += formSize;
@@ -277,66 +275,6 @@ else if (legendPosition == Legend.LegendPosition.BELOW_CHART_RIGHT) {
277275
break;
278276

279277
case PIECHART_CENTER:
280-
{
281-
// contains the stacked legend size in pixels
282-
float stack = 0f;
283-
boolean wasStacked = false;
284-
285-
posX = mViewPortHandler.getChartWidth()
286-
/ 2f
287-
+ (direction == Legend.LegendDirection.LEFT_TO_RIGHT ? -mLegend.mTextWidthMax / 2f
288-
: mLegend.mTextWidthMax / 2f);
289-
posY = mViewPortHandler.getChartHeight() / 2f - mLegend.mNeededHeight / 2f
290-
+ mLegend.getYOffset();
291-
292-
for (int i = 0; i < labels.length; i++) {
293-
294-
boolean drawingForm = colors[i] != ColorTemplate.COLOR_SKIP;
295-
float x = posX;
296-
297-
if (drawingForm) {
298-
if (direction == Legend.LegendDirection.LEFT_TO_RIGHT)
299-
x += stack;
300-
else
301-
x -= formSize - stack;
302-
303-
drawForm(c, x, posY, i, mLegend);
304-
305-
if (direction == Legend.LegendDirection.LEFT_TO_RIGHT)
306-
x += formSize;
307-
}
308-
309-
if (labels[i] != null) {
310-
311-
if (drawingForm && !wasStacked)
312-
x += direction == Legend.LegendDirection.LEFT_TO_RIGHT ? formToTextSpace
313-
: -formToTextSpace;
314-
else if (wasStacked)
315-
x = posX;
316-
317-
if (direction == Legend.LegendDirection.RIGHT_TO_LEFT)
318-
x -= Utils.calcTextWidth(mLegendLabelPaint, labels[i]);
319-
320-
if (!wasStacked) {
321-
drawLabel(c, x, posY + mLegend.mTextHeightMax / 2f, labels[i]);
322-
323-
posY += textDrop;
324-
} else {
325-
posY += mLegend.mTextHeightMax * 3f;
326-
drawLabel(c, x, posY - mLegend.mTextHeightMax, labels[i]);
327-
}
328-
329-
// make a step down
330-
posY += mLegend.getYEntrySpace();
331-
stack = 0f;
332-
} else {
333-
stack += formSize + stackSpace;
334-
wasStacked = true;
335-
}
336-
}
337-
}
338-
break;
339-
340278
case RIGHT_OF_CHART:
341279
case RIGHT_OF_CHART_CENTER:
342280
case RIGHT_OF_CHART_INSIDE:
@@ -348,34 +286,42 @@ else if (wasStacked)
348286
float stack = 0f;
349287
boolean wasStacked = false;
350288

351-
boolean isRightAligned = legendPosition == Legend.LegendPosition.RIGHT_OF_CHART
352-
||
353-
legendPosition == Legend.LegendPosition.RIGHT_OF_CHART_CENTER ||
354-
legendPosition == Legend.LegendPosition.RIGHT_OF_CHART_INSIDE;
355-
356-
if (isRightAligned) {
357-
posX = mViewPortHandler.getChartWidth() - xoffset;
358-
if (direction == Legend.LegendDirection.LEFT_TO_RIGHT)
359-
posX -= mLegend.mTextWidthMax;
289+
if (legendPosition == Legend.LegendPosition.PIECHART_CENTER) {
290+
posX = mViewPortHandler.getChartWidth() / 2f
291+
+ (direction == Legend.LegendDirection.LEFT_TO_RIGHT ? -mLegend.mTextWidthMax / 2f
292+
: mLegend.mTextWidthMax / 2f);
293+
posY = mViewPortHandler.getChartHeight() / 2f - mLegend.mNeededHeight / 2f
294+
+ mLegend.getYOffset();
360295
} else {
361-
posX = xoffset;
362-
if (direction == Legend.LegendDirection.RIGHT_TO_LEFT)
363-
posX += mLegend.mTextWidthMax;
364-
}
296+
boolean isRightAligned = legendPosition == Legend.LegendPosition.RIGHT_OF_CHART
297+
||
298+
legendPosition == Legend.LegendPosition.RIGHT_OF_CHART_CENTER ||
299+
legendPosition == Legend.LegendPosition.RIGHT_OF_CHART_INSIDE;
365300

366-
if (legendPosition == Legend.LegendPosition.RIGHT_OF_CHART ||
367-
legendPosition == Legend.LegendPosition.LEFT_OF_CHART) {
368-
posY = mViewPortHandler.contentTop() + yoffset;
369-
} else if (legendPosition == Legend.LegendPosition.RIGHT_OF_CHART_CENTER ||
370-
legendPosition == Legend.LegendPosition.LEFT_OF_CHART_CENTER) {
371-
posY = mViewPortHandler.getChartHeight() / 2f - mLegend.mNeededHeight / 2f;
372-
} else /*
373-
* if (legendPosition ==
374-
* Legend.LegendPosition.RIGHT_OF_CHART_INSIDE ||
375-
* legendPosition ==
376-
* Legend.LegendPosition.LEFT_OF_CHART_INSIDE)
377-
*/{
378-
posY = mViewPortHandler.contentTop() + yoffset;
301+
if (isRightAligned) {
302+
posX = mViewPortHandler.getChartWidth() - xoffset;
303+
if (direction == Legend.LegendDirection.LEFT_TO_RIGHT)
304+
posX -= mLegend.mTextWidthMax;
305+
} else {
306+
posX = xoffset;
307+
if (direction == Legend.LegendDirection.RIGHT_TO_LEFT)
308+
posX += mLegend.mTextWidthMax;
309+
}
310+
311+
if (legendPosition == Legend.LegendPosition.RIGHT_OF_CHART ||
312+
legendPosition == Legend.LegendPosition.LEFT_OF_CHART) {
313+
posY = mViewPortHandler.contentTop() + yoffset;
314+
} else if (legendPosition == Legend.LegendPosition.RIGHT_OF_CHART_CENTER ||
315+
legendPosition == Legend.LegendPosition.LEFT_OF_CHART_CENTER) {
316+
posY = mViewPortHandler.getChartHeight() / 2f - mLegend.mNeededHeight / 2f;
317+
} else /*
318+
* if (legendPosition ==
319+
* Legend.LegendPosition.RIGHT_OF_CHART_INSIDE ||
320+
* legendPosition ==
321+
* Legend.LegendPosition.LEFT_OF_CHART_INSIDE)
322+
*/{
323+
posY = mViewPortHandler.contentTop() + yoffset;
324+
}
379325
}
380326

381327
for (int i = 0; i < labels.length; i++) {
@@ -389,7 +335,7 @@ else if (wasStacked)
389335
else
390336
x -= formSize - stack;
391337

392-
drawForm(c, x, posY, i, mLegend);
338+
drawForm(c, x, posY + formYOffset, i, mLegend);
393339

394340
if (direction == Legend.LegendDirection.LEFT_TO_RIGHT)
395341
x += formSize;
@@ -407,16 +353,14 @@ else if (wasStacked)
407353
x -= Utils.calcTextWidth(mLegendLabelPaint, labels[i]);
408354

409355
if (!wasStacked) {
410-
drawLabel(c, x, posY + mLegend.mTextHeightMax / 2f, labels[i]);
411-
412-
posY += textDrop;
356+
drawLabel(c, x, posY + labelLineHeight, labels[i]);
413357
} else {
414-
posY += mLegend.mTextHeightMax * 3f;
415-
drawLabel(c, x, posY - mLegend.mTextHeightMax, labels[i]);
358+
posY += labelLineHeight + labelLineSpacing;
359+
drawLabel(c, x, posY + labelLineHeight, labels[i]);
416360
}
417361

418362
// make a step down
419-
posY += mLegend.getYEntrySpace();
363+
posY += labelLineHeight + labelLineSpacing;
420364
stack = 0f;
421365
} else {
422366
stack += formSize + stackSpace;

MPChartLib/src/com/github/mikephil/charting/utils/Utils.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -174,6 +174,16 @@ public static int calcTextHeight(Paint paint, String demoText) {
174174
return r.height();
175175
}
176176

177+
public static float getLineHeight(Paint paint) {
178+
Paint.FontMetrics metrics = paint.getFontMetrics();
179+
return metrics.descent - metrics.ascent;
180+
}
181+
182+
public static float getLineSpacing(Paint paint) {
183+
Paint.FontMetrics metrics = paint.getFontMetrics();
184+
return metrics.ascent - metrics.top + metrics.bottom;
185+
}
186+
177187
/**
178188
* calculates the approximate size of a text, depending on a demo text
179189
* avoid repeated calls (e.g. inside drawing methods)

0 commit comments

Comments
 (0)