说明:下文中的bug已经在MPAndroidChart饼图(PieChart)Value值重叠的解决方法(二)中完美解决了,可以去看看。
先看下前后对比的效果图
修改前.jpg 修改后.jpg背景
项目做完出来的时候,我就发现了这个问题,奈何在网上没找解决办法,而我又是个Android渣渣,本来准备蒙混过关的,可是测试一定要我改,没办法只能看看MPAndroidChart里的可能涉及到的源码,看下能不能改好。所以,如果有不对和优化的地方,希望大家能指出,相互进步。
已知bug
(已经在MPAndroidChart饼图(PieChart)Value值重叠的解决方法(二)中解决了)
PieChart不能设置为可以转动,即pieChart.setRotationEnabled(false);
要设置成false,如果转动,会在转动的时候导致值的位置错乱,知道怎么解决的同学请指点,有空我也看看能不能解决。
思路
网上有一个解决方案是,把占比较小部分的值不显示出来,但是博主也说,还是会有重叠的可能,不过大家可以看下地址
我的思路是,每次都记住上一个值Y方向位置,和这次对比,如果间距小于了值字体的高度,则改变本次画值的位置
实现步骤
- 通过观察原生态的PieChart,发现饼图绘制过程,其实画值的过程是由
mRenderer
实现的,如下:
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
if (mData == null)
return;
mRenderer.drawData(canvas);
if (valuesToHighlight())
mRenderer.drawHighlighted(canvas, mIndicesToHighlight);
mRenderer.drawExtras(canvas);
mRenderer.drawValues(canvas);
mLegendRenderer.renderLegend(canvas);
drawDescription(canvas);
drawMarkers(canvas);
}
所以,我们只需要修改mRenderer
中画图的实现步骤就好了,那我们就需要把这个mRenderer
替换成我们自己定义的PieChartRenderer,而mRenderer
又是在下面这个方法中初始化的:
@Override
protected void init() {
super.init();
mRenderer = new PieChartRenderer(this, mAnimator, mViewPortHandler);
mXAxis = null;
mHighlighter = new PieHighlighter(this);
}
因为我没找到可以直接设置mRenderer的方法,所以我们需要自己创建一个PieChart的子类,重写init()
方法,让mRenderer变成我们自己的PieChartRenderer。
- 先创建我们自己的PieChartRenderer吧,创建一个类继承PieChartRenderer,有一个被注释的
drawValues(Canvas c)
方法是饼图左右两边上边对其,效果可以自己打开试下(因为我感觉遍历了太多次,所以就没有使用),其他的代码中关键部分都有说明,就不细说了,代码如下:
public class MyPieChartRenderer extends PieChartRenderer {
private static final String TAG = "MyPieChartRenderer";
public MyPieChartRenderer(PieChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
}
String text = "2.0%";
/**
* 这个方法,左边是从下往上画,右边是从上往下画
* @param c
*/
@Override
public void drawValues(Canvas c) {
Rect rect = new Rect();
getPaintEntryLabels().getTextBounds(text, 0, text.length(), rect);
int textHeight = rect.height();//文本的高度
MPPointF center = mChart.getCenterCircleBox();
// get whole the radius
float radius = mChart.getRadius();
float rotationAngle = mChart.getRotationAngle();
float[] drawAngles = mChart.getDrawAngles();
float[] absoluteAngles = mChart.getAbsoluteAngles();
float phaseX = mAnimator.getPhaseX();
float phaseY = mAnimator.getPhaseY();
final float holeRadiusPercent = mChart.getHoleRadius() / 100.f;
float labelRadiusOffset = radius / 10f * 3.6f;
if (mChart.isDrawHoleEnabled()) {
labelRadiusOffset = (radius - (radius * holeRadiusPercent)) / 2f;
}
final float labelRadius = radius - labelRadiusOffset;
PieData data = mChart.getData();
List<IPieDataSet> dataSets = data.getDataSets();
float yValueSum = data.getYValueSum();
boolean drawEntryLabels = mChart.isDrawEntryLabelsEnabled();
float angle;
int xIndex = 0;
c.save();
float offset = Utils.convertDpToPixel(5.f);
for (int i = 0; i < dataSets.size(); i++) {
IPieDataSet dataSet = dataSets.get(i);
final boolean drawValues = dataSet.isDrawValuesEnabled();
if (!drawValues && !drawEntryLabels)
continue;
final PieDataSet.ValuePosition xValuePosition = dataSet.getXValuePosition();
final PieDataSet.ValuePosition yValuePosition = dataSet.getYValuePosition();
// apply the text-styling defined by the DataSet
applyValueTextStyle(dataSet);
float lineHeight = Utils.calcTextHeight(mValuePaint, "Q")
+ Utils.convertDpToPixel(4f);
IValueFormatter formatter = dataSet.getValueFormatter();
int entryCount = dataSet.getEntryCount();
mValueLinePaint.setColor(dataSet.getValueLineColor());
mValueLinePaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getValueLineWidth()));
final float sliceSpace = getSliceSpace(dataSet);
MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
float lastPositionOfLeft = 0;
float lastPositionOfRight = 0;
for (int j = 0; j < entryCount; j++) {
PieEntry entry = dataSet.getEntryForIndex(j);
if (xIndex == 0)
angle = 0.f;
else
angle = absoluteAngles[xIndex - 1] * phaseX;
final float sliceAngle = drawAngles[xIndex];
final float sliceSpaceMiddleAngle = sliceSpace / (Utils.FDEG2RAD * labelRadius);
// offset needed to center the drawn text in the slice
final float angleOffset = (sliceAngle - sliceSpaceMiddleAngle / 2.f) / 2.f;
angle = angle + angleOffset;
final float transformedAngle = rotationAngle + angle * phaseY;
float value = mChart.isUsePercentValuesEnabled() ? entry.getY()
/ yValueSum * 100f : entry.getY();
final float sliceXBase = (float) Math.cos(transformedAngle * Utils.FDEG2RAD);
final float sliceYBase = (float) Math.sin(transformedAngle * Utils.FDEG2RAD);
final boolean drawXOutside = drawEntryLabels &&
xValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
final boolean drawYOutside = drawValues &&
yValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
final boolean drawXInside = drawEntryLabels &&
xValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
final boolean drawYInside = drawValues &&
yValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
if (drawXOutside || drawYOutside) {
final float valueLineLength1 = dataSet.getValueLinePart1Length();
final float valueLineLength2 = dataSet.getValueLinePart2Length();
final float valueLinePart1OffsetPercentage = dataSet.getValueLinePart1OffsetPercentage() / 100.f;
float pt2x, pt2y;
float labelPtx, labelPty;
float line1Radius;
if (mChart.isDrawHoleEnabled())
line1Radius = (radius - (radius * holeRadiusPercent))
* valueLinePart1OffsetPercentage
+ (radius * holeRadiusPercent);
else
line1Radius = radius * valueLinePart1OffsetPercentage;
final float polyline2Width = dataSet.isValueLineVariableLength()
? labelRadius * valueLineLength2 * (float) Math.abs(Math.sin(
transformedAngle * Utils.FDEG2RAD))
: labelRadius * valueLineLength2;
final float pt0x = line1Radius * sliceXBase + center.x;
final float pt0y = line1Radius * sliceYBase + center.y;
final float pt1x = labelRadius * (1 + valueLineLength1) * sliceXBase + center.x;
final float pt1y = labelRadius * (1 + valueLineLength1) * sliceYBase + center.y;
//左右算法不一样,左边是从下往上排的,即你可以理解为饼图是顺时针方向,从零点排到12点的360度圆形,建议先看else里的,即右边的,方便理解
if (transformedAngle % 360.0 >= 90.0 && transformedAngle % 360.0 <= 270.0) {//左边部分
// pt2x = pt1x - polyline2Width;
pt2x = center.x - radius - 5;
if (lastPositionOfLeft == 0) {//第一个不用管
pt2y = pt1y;
} else {
if (lastPositionOfLeft - pt1y < textHeight) {//如果上一个labley的位置减去计算出的pt1y的位置间距小于lable的高度,则需要在计算出的y基础上加上差的间距
pt2y = pt1y - (textHeight - (lastPositionOfLeft - pt1y));//例如:lable高度5,计算出的pt1y位置10,上一个labley的位置12,则间距只有lastPositionOfRight-pt1y=2,还需要减去少的textHeight-(lastPositionOfRight-pt1y)=3才行
} else {
pt2y = pt1y;
}
}
lastPositionOfLeft = pt2y;//记录上一个lableY方向的位置
mValuePaint.setTextAlign(Paint.Align.RIGHT);
if (drawXOutside)
getPaintEntryLabels().setTextAlign(Paint.Align.RIGHT);
labelPtx = pt2x - offset;
labelPty = pt2y;
} else {//右边部分
// pt2x = pt1x + polyline2Width;
pt2x = center.x + radius + 5;
if (lastPositionOfRight == 0) {//第一个不用管
pt2y = pt1y;
} else {
if (pt1y - lastPositionOfRight < textHeight) {//如果计算出的pt1y的位置减去上一个labley的位置间距小于lable的高度,则需要在计算出的y基础上加上差的间距
pt2y = pt1y + (textHeight - (pt1y - lastPositionOfRight));//例如:lable高度5,计算出的pt1y位置10,上一个labley的位置8,则间距只有pt1y-lastPositionOfRight=2,还需要加上少的textHeight-(pt1y-lastPositionOfRight)=3才行
} else {
pt2y = pt1y;
}
}
lastPositionOfRight = pt2y;//记录上一个lableY方向的位置
mValuePaint.setTextAlign(Paint.Align.LEFT);
if (drawXOutside)
getPaintEntryLabels().setTextAlign(Paint.Align.LEFT);
labelPtx = pt2x + offset;
labelPty = pt2y;
}
if (dataSet.getValueLineColor() != ColorTemplate.COLOR_NONE) {
c.drawLine(pt0x, pt0y, pt1x, pt1y, mValueLinePaint);
c.drawLine(pt1x, pt1y, pt2x, pt2y, mValueLinePaint);
}
// draw everything, depending on settings
if (drawXOutside && drawYOutside) {
drawValue(c,
formatter,
value,
entry,
0,
labelPtx,
labelPty,
dataSet.getValueTextColor(j));
if (j < data.getEntryCount() && entry.getLabel() != null) {
drawEntryLabel(c, entry.getLabel(), labelPtx, labelPty + lineHeight);
}
} else if (drawXOutside) {
if (j < data.getEntryCount() && entry.getLabel() != null) {
drawEntryLabel(c, entry.getLabel(), labelPtx, labelPty + lineHeight / 2.f);
}
} else if (drawYOutside) {
drawValue(c, formatter, value, entry, 0, labelPtx, labelPty + lineHeight / 2.f, dataSet
.getValueTextColor(j));
}
}
if (drawXInside || drawYInside) {
// calculate the text position
float x = labelRadius * sliceXBase + center.x;
float y = labelRadius * sliceYBase + center.y;
mValuePaint.setTextAlign(Paint.Align.CENTER);
// draw everything, depending on settings
if (drawXInside && drawYInside) {
drawValue(c, formatter, value, entry, 0, x, y, dataSet.getValueTextColor(j));
if (j < data.getEntryCount() && entry.getLabel() != null) {
drawEntryLabel(c, entry.getLabel(), x, y + lineHeight);
}
} else if (drawXInside) {
if (j < data.getEntryCount() && entry.getLabel() != null) {
drawEntryLabel(c, entry.getLabel(), x, y + lineHeight / 2f);
}
} else if (drawYInside) {
drawValue(c, formatter, value, entry, 0, x, y + lineHeight / 2f, dataSet.getValueTextColor(j));
}
}
if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
Drawable icon = entry.getIcon();
float x = (labelRadius + iconsOffset.y) * sliceXBase + center.x;
float y = (labelRadius + iconsOffset.y) * sliceYBase + center.y;
y += iconsOffset.x;
Utils.drawImage(
c,
icon,
(int) x,
(int) y,
icon.getIntrinsicWidth(),
icon.getIntrinsicHeight());
}
xIndex++;
}
MPPointF.recycleInstance(iconsOffset);
}
MPPointF.recycleInstance(center);
c.restore();
}
/**
* 这个方法,是两侧都上往下排列,保证上面整齐
*/
// @Override
// public void drawValues(Canvas c) {
//
//
// Rect rect = new Rect();
// getPaintEntryLabels().getTextBounds(text, 0, text.length(), rect);
// int textHeight = rect.height();//文本的高度
//
// MPPointF center = mChart.getCenterCircleBox();
//
// // get whole the radius
// float radius = mChart.getRadius();
// float rotationAngle = mChart.getRotationAngle();
// float[] drawAngles = mChart.getDrawAngles();
// float[] absoluteAngles = mChart.getAbsoluteAngles();
//
// float phaseX = mAnimator.getPhaseX();
// float phaseY = mAnimator.getPhaseY();
//
// final float holeRadiusPercent = mChart.getHoleRadius() / 100.f;
// float labelRadiusOffset = radius / 10f * 3.6f;
//
// if (mChart.isDrawHoleEnabled()) {
// labelRadiusOffset = (radius - (radius * holeRadiusPercent)) / 2f;
// }
//
// final float labelRadius = radius - labelRadiusOffset;
//
// PieData data = mChart.getData();
// List<IPieDataSet> dataSets = data.getDataSets();
//
// float yValueSum = data.getYValueSum();
//
// boolean drawEntryLabels = mChart.isDrawEntryLabelsEnabled();
//
// float angle;
// int xIndex = 0;
//
// c.save();
//
// float offset = Utils.convertDpToPixel(5.f);
//
// for (int i = 0; i < dataSets.size(); i++) {
//
// IPieDataSet dataSet = dataSets.get(i);
//
// final boolean drawValues = dataSet.isDrawValuesEnabled();
//
// if (!drawValues && !drawEntryLabels)
// continue;
//
// final PieDataSet.ValuePosition xValuePosition = dataSet.getXValuePosition();
// final PieDataSet.ValuePosition yValuePosition = dataSet.getYValuePosition();
//
// // apply the text-styling defined by the DataSet
// applyValueTextStyle(dataSet);
//
// float lineHeight = Utils.calcTextHeight(mValuePaint, "Q")
// + Utils.convertDpToPixel(4f);
//
// IValueFormatter formatter = dataSet.getValueFormatter();
//
// int entryCount = dataSet.getEntryCount();
//
// mValueLinePaint.setColor(dataSet.getValueLineColor());
// mValueLinePaint.setStrokeWidth(Utils.convertDpToPixel(dataSet.getValueLineWidth()));
//
// final float sliceSpace = getSliceSpace(dataSet);
//
// MPPointF iconsOffset = MPPointF.getInstance(dataSet.getIconsOffset());
// iconsOffset.x = Utils.convertDpToPixel(iconsOffset.x);
// iconsOffset.y = Utils.convertDpToPixel(iconsOffset.y);
//
// float lastPositionOfLeft = 0;
// float lastPositionOfRight = 0;
//
// //画右边
// for (int j = 0; j < entryCount; j++) {
//
// PieEntry entry = dataSet.getEntryForIndex(j);
//
// if (xIndex == 0)
// angle = 0.f;
// else
// angle = absoluteAngles[xIndex - 1] * phaseX;
//
// final float sliceAngle = drawAngles[xIndex];
// final float sliceSpaceMiddleAngle = sliceSpace / (Utils.FDEG2RAD * labelRadius);
//
// // offset needed to center the drawn text in the slice
// final float angleOffset = (sliceAngle - sliceSpaceMiddleAngle / 2.f) / 2.f;
//
// angle = angle + angleOffset;
//
// final float transformedAngle = rotationAngle + angle * phaseY;
//
// float value = mChart.isUsePercentValuesEnabled() ? entry.getY()
// / yValueSum * 100f : entry.getY();
//
// final float sliceXBase = (float) Math.cos(transformedAngle * Utils.FDEG2RAD);
// final float sliceYBase = (float) Math.sin(transformedAngle * Utils.FDEG2RAD);
//
// final boolean drawXOutside = drawEntryLabels &&
// xValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
// final boolean drawYOutside = drawValues &&
// yValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
// final boolean drawXInside = drawEntryLabels &&
// xValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
// final boolean drawYInside = drawValues &&
// yValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
//
// if (drawXOutside || drawYOutside) {
//
// final float valueLineLength1 = dataSet.getValueLinePart1Length();
// final float valueLineLength2 = dataSet.getValueLinePart2Length();
// final float valueLinePart1OffsetPercentage = dataSet.getValueLinePart1OffsetPercentage() / 100.f;
//
// float pt2x, pt2y;
// float labelPtx, labelPty;
//
// float line1Radius;
//
// if (mChart.isDrawHoleEnabled())
// line1Radius = (radius - (radius * holeRadiusPercent))
// * valueLinePart1OffsetPercentage
// + (radius * holeRadiusPercent);
// else
// line1Radius = radius * valueLinePart1OffsetPercentage;
//
// final float polyline2Width = dataSet.isValueLineVariableLength()
// ? labelRadius * valueLineLength2 * (float) Math.abs(Math.sin(
// transformedAngle * Utils.FDEG2RAD))
// : labelRadius * valueLineLength2;
//
// final float pt0x = line1Radius * sliceXBase + center.x;
// final float pt0y = line1Radius * sliceYBase + center.y;
//
// final float pt1x = labelRadius * (1 + valueLineLength1) * sliceXBase + center.x;
// final float pt1y = labelRadius * (1 + valueLineLength1) * sliceYBase + center.y;
//
// //左右算法不一样,左边是从下往上排的,即你可以理解为饼图是顺时针方向,从零点排到12点的360度圆形,建议先看else里的,即右边的,方便理解
// if (transformedAngle % 360.0 >= 90.0 && transformedAngle % 360.0 <= 270.0) {//左边部分
//// pt2x = center.x - radius - 5;
//// if (lastPositionOfLeft == 0) {//第一个不用管
//// pt2y = pt1y;
//// } else {
//// if (lastPositionOfLeft - pt1y < textHeight) {//如果上一个labley的位置减去计算出的pt1y的位置间距小于lable的高度,则需要在计算出的y基础上加上差的间距
//// pt2y = pt1y - (textHeight - (lastPositionOfLeft - pt1y));//例如:lable高度5,计算出的pt1y位置10,上一个labley的位置12,则间距只有lastPositionOfRight-pt1y=2,还需要减去少的textHeight-(lastPositionOfRight-pt1y)=3才行
//// } else {
//// pt2y = pt1y;
//// }
//// }
//// lastPositionOfLeft = pt2y;//记录上一个lableY方向的位置
////
//// mValuePaint.setTextAlign(Paint.Align.RIGHT);
////
//// if (drawXOutside)
//// getPaintEntryLabels().setTextAlign(Paint.Align.RIGHT);
////
//// labelPtx = pt2x - offset;
//// labelPty = pt2y;
// break;
// } else {//右边部分
//// pt2x = pt1x + polyline2Width;
// pt2x = center.x + radius + 5;
// if (lastPositionOfRight == 0) {//第一个不用管
// pt2y = pt1y;
// } else {
// if (pt1y - lastPositionOfRight < textHeight) {//如果计算出的pt1y的位置减去上一个labley的位置间距小于lable的高度,则需要在计算出的y基础上加上差的间距
// pt2y = pt1y + (textHeight - (pt1y - lastPositionOfRight));//例如:lable高度5,计算出的pt1y位置10,上一个labley的位置8,则间距只有pt1y-lastPositionOfRight=2,还需要加上少的textHeight-(pt1y-lastPositionOfRight)=3才行
// } else {
// pt2y = pt1y;
// }
// }
// lastPositionOfRight = pt2y;//记录上一个lableY方向的位置
// mValuePaint.setTextAlign(Paint.Align.LEFT);
//
// if (drawXOutside)
// getPaintEntryLabels().setTextAlign(Paint.Align.LEFT);
//
// labelPtx = pt2x + offset;
// labelPty = pt2y;
// }
//
// if (dataSet.getValueLineColor() != ColorTemplate.COLOR_NONE) {
// c.drawLine(pt0x, pt0y, pt1x, pt1y, mValueLinePaint);
// c.drawLine(pt1x, pt1y, pt2x, pt2y, mValueLinePaint);
// }
//
// // draw everything, depending on settings
// if (drawXOutside && drawYOutside) {
//
// drawValue(c,
// formatter,
// value,
// entry,
// 0,
// labelPtx,
// labelPty,
// dataSet.getValueTextColor(j));
//
// if (j < data.getEntryCount() && entry.getLabel() != null) {
// drawEntryLabel(c, entry.getLabel(), labelPtx, labelPty + lineHeight);
// }
//
// } else if (drawXOutside) {
// if (j < data.getEntryCount() && entry.getLabel() != null) {
// drawEntryLabel(c, entry.getLabel(), labelPtx, labelPty + lineHeight / 2.f);
// }
// } else if (drawYOutside) {
//
// drawValue(c, formatter, value, entry, 0, labelPtx, labelPty + lineHeight / 2.f, dataSet
// .getValueTextColor(j));
// }
// }
//
// if (drawXInside || drawYInside) {
// // calculate the text position
// float x = labelRadius * sliceXBase + center.x;
// float y = labelRadius * sliceYBase + center.y;
//
// mValuePaint.setTextAlign(Paint.Align.CENTER);
//
// // draw everything, depending on settings
// if (drawXInside && drawYInside) {
//
// drawValue(c, formatter, value, entry, 0, x, y, dataSet.getValueTextColor(j));
//
// if (j < data.getEntryCount() && entry.getLabel() != null) {
// drawEntryLabel(c, entry.getLabel(), x, y + lineHeight);
// }
//
// } else if (drawXInside) {
// if (j < data.getEntryCount() && entry.getLabel() != null) {
// drawEntryLabel(c, entry.getLabel(), x, y + lineHeight / 2f);
// }
// } else if (drawYInside) {
//
// drawValue(c, formatter, value, entry, 0, x, y + lineHeight / 2f, dataSet.getValueTextColor(j));
// }
// }
//
// if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
//
// Drawable icon = entry.getIcon();
//
// float x = (labelRadius + iconsOffset.y) * sliceXBase + center.x;
// float y = (labelRadius + iconsOffset.y) * sliceYBase + center.y;
// y += iconsOffset.x;
//
// Utils.drawImage(
// c,
// icon,
// (int) x,
// (int) y,
// icon.getIntrinsicWidth(),
// icon.getIntrinsicHeight());
// }
//
// xIndex++;
// }
//
// //画左边
// xIndex = entryCount-1;
// for (int j = entryCount - 1; j >= 0; j--) {
//
// PieEntry entry = dataSet.getEntryForIndex(j);
//
// if (xIndex == 0)
// angle = 0.f;
// else
// angle = absoluteAngles[xIndex - 1] * phaseX;
//
// final float sliceAngle = drawAngles[xIndex];
// final float sliceSpaceMiddleAngle = sliceSpace / (Utils.FDEG2RAD * labelRadius);
//
// // offset needed to center the drawn text in the slice
// final float angleOffset = (sliceAngle - sliceSpaceMiddleAngle / 2.f) / 2.f;
//
// angle = angle + angleOffset;
//
// final float transformedAngle = rotationAngle + angle * phaseY;
//
// float value = mChart.isUsePercentValuesEnabled() ? entry.getY()
// / yValueSum * 100f : entry.getY();
//
// final float sliceXBase = (float) Math.cos(transformedAngle * Utils.FDEG2RAD);
// final float sliceYBase = (float) Math.sin(transformedAngle * Utils.FDEG2RAD);
//
// final boolean drawXOutside = drawEntryLabels &&
// xValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
// final boolean drawYOutside = drawValues &&
// yValuePosition == PieDataSet.ValuePosition.OUTSIDE_SLICE;
// final boolean drawXInside = drawEntryLabels &&
// xValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
// final boolean drawYInside = drawValues &&
// yValuePosition == PieDataSet.ValuePosition.INSIDE_SLICE;
//
// if (drawXOutside || drawYOutside) {
//
// final float valueLineLength1 = dataSet.getValueLinePart1Length();
// final float valueLineLength2 = dataSet.getValueLinePart2Length();
// final float valueLinePart1OffsetPercentage = dataSet.getValueLinePart1OffsetPercentage() / 100.f;
//
// float pt2x, pt2y;
// float labelPtx, labelPty;
//
// float line1Radius;
//
// if (mChart.isDrawHoleEnabled())
// line1Radius = (radius - (radius * holeRadiusPercent))
// * valueLinePart1OffsetPercentage
// + (radius * holeRadiusPercent);
// else
// line1Radius = radius * valueLinePart1OffsetPercentage;
//
// final float polyline2Width = dataSet.isValueLineVariableLength()
// ? labelRadius * valueLineLength2 * (float) Math.abs(Math.sin(
// transformedAngle * Utils.FDEG2RAD))
// : labelRadius * valueLineLength2;
//
// final float pt0x = line1Radius * sliceXBase + center.x;
// final float pt0y = line1Radius * sliceYBase + center.y;
//
// final float pt1x = labelRadius * (1 + valueLineLength1) * sliceXBase + center.x;
// final float pt1y = labelRadius * (1 + valueLineLength1) * sliceYBase + center.y;
//
// //左右算法不一样,左边是从下往上排的,即你可以理解为饼图是顺时针方向,从零点排到12点的360度圆形,建议先看else里的,即右边的,方便理解
// if (transformedAngle % 360.0 >= 90.0 && transformedAngle % 360.0 <= 270.0) {//左边部分
// pt2x = center.x - radius - 5;
// if (lastPositionOfLeft == 0) {//第一个不用管
// pt2y = pt1y;
// } else {
// if (pt1y - lastPositionOfLeft < textHeight) {//如果上一个labley的位置减去计算出的pt1y的位置间距小于lable的高度,则需要在计算出的y基础上加上差的间距
// pt2y = pt1y + (textHeight - (pt1y - lastPositionOfLeft));//例如:lable高度5,计算出的pt1y位置10,上一个labley的位置12,则间距只有lastPositionOfRight-pt1y=2,还需要减去少的textHeight-(lastPositionOfRight-pt1y)=3才行
// } else {
// pt2y = pt1y;
// }
// }
// lastPositionOfLeft = pt2y;//记录上一个lableY方向的位置
//
// mValuePaint.setTextAlign(Paint.Align.RIGHT);
//
// if (drawXOutside)
// getPaintEntryLabels().setTextAlign(Paint.Align.RIGHT);
//
// labelPtx = pt2x - offset;
// labelPty = pt2y;
//
// } else {//右边部分
//// pt2x = center.x + radius + 5;
//// if (lastPositionOfRight == 0) {//第一个不用管
//// pt2y = pt1y;
//// } else {
//// if (pt1y - lastPositionOfRight < textHeight) {//如果计算出的pt1y的位置减去上一个labley的位置间距小于lable的高度,则需要在计算出的y基础上加上差的间距
//// pt2y = pt1y + (textHeight - (pt1y - lastPositionOfRight));//例如:lable高度5,计算出的pt1y位置10,上一个labley的位置8,则间距只有pt1y-lastPositionOfRight=2,还需要加上少的textHeight-(pt1y-lastPositionOfRight)=3才行
//// } else {
//// pt2y = pt1y;
//// }
//// }
//// lastPositionOfRight = pt2y;//记录上一个lableY方向的位置
//// mValuePaint.setTextAlign(Paint.Align.LEFT);
////
//// if (drawXOutside)
//// getPaintEntryLabels().setTextAlign(Paint.Align.LEFT);
////
//// labelPtx = pt2x + offset;
//// labelPty = pt2y;
// continue;
// }
//
// if (dataSet.getValueLineColor() != ColorTemplate.COLOR_NONE) {
// c.drawLine(pt0x, pt0y, pt1x, pt1y, mValueLinePaint);
// c.drawLine(pt1x, pt1y, pt2x, pt2y, mValueLinePaint);
// }
//
// // draw everything, depending on settings
// if (drawXOutside && drawYOutside) {
//
// drawValue(c,
// formatter,
// value,
// entry,
// 0,
// labelPtx,
// labelPty,
// dataSet.getValueTextColor(j));
//
// if (j < data.getEntryCount() && entry.getLabel() != null) {
// drawEntryLabel(c, entry.getLabel(), labelPtx, labelPty + lineHeight);
// }
//
// } else if (drawXOutside) {
// if (j < data.getEntryCount() && entry.getLabel() != null) {
// drawEntryLabel(c, entry.getLabel(), labelPtx, labelPty + lineHeight / 2.f);
// }
// } else if (drawYOutside) {
//
// drawValue(c, formatter, value, entry, 0, labelPtx, labelPty + lineHeight / 2.f, dataSet
// .getValueTextColor(j));
// }
// }
//
// if (drawXInside || drawYInside) {
// // calculate the text position
// float x = labelRadius * sliceXBase + center.x;
// float y = labelRadius * sliceYBase + center.y;
//
// mValuePaint.setTextAlign(Paint.Align.CENTER);
//
// // draw everything, depending on settings
// if (drawXInside && drawYInside) {
//
// drawValue(c, formatter, value, entry, 0, x, y, dataSet.getValueTextColor(j));
//
// if (j < data.getEntryCount() && entry.getLabel() != null) {
// drawEntryLabel(c, entry.getLabel(), x, y + lineHeight);
// }
//
// } else if (drawXInside) {
// if (j < data.getEntryCount() && entry.getLabel() != null) {
// drawEntryLabel(c, entry.getLabel(), x, y + lineHeight / 2f);
// }
// } else if (drawYInside) {
//
// drawValue(c, formatter, value, entry, 0, x, y + lineHeight / 2f, dataSet.getValueTextColor(j));
// }
// }
//
// if (entry.getIcon() != null && dataSet.isDrawIconsEnabled()) {
//
// Drawable icon = entry.getIcon();
//
// float x = (labelRadius + iconsOffset.y) * sliceXBase + center.x;
// float y = (labelRadius + iconsOffset.y) * sliceYBase + center.y;
// y += iconsOffset.x;
//
// Utils.drawImage(
// c,
// icon,
// (int) x,
// (int) y,
// icon.getIntrinsicWidth(),
// icon.getIntrinsicHeight());
// }
//
// xIndex--;
// }
//
// MPPointF.recycleInstance(iconsOffset);
// }
// MPPointF.recycleInstance(center);
// c.restore();
// }
}
- 再创建一个PieChart的子类,重新父类
init()
方法,由于我是在ViewPager中使用的,顺便处理了下滑动冲突,不需要的同学,可以把onTouchEvent(MotionEvent evt)
删掉,代码如下:
public class MyPieChart extends PieChart {
PointF downPoint = new PointF();
public MyPieChart(Context context) {
super(context);
}
public MyPieChart(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyPieChart(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void init() {
super.init();
//此处把mRenderer替换成我们自己的PieChartRenderer
mRenderer = new MyPieChartRenderer(this, mAnimator, mViewPortHandler);
}
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouchEvent(MotionEvent evt) {
switch (evt.getAction()) {
case MotionEvent.ACTION_DOWN:
downPoint.x = evt.getX();
downPoint.y = evt.getY();
break;
case MotionEvent.ACTION_MOVE:
if (Math.abs(evt.getX() - downPoint.x) > 5 || Math.abs(evt.getY() - downPoint.y) > 5) {
getParent().requestDisallowInterceptTouchEvent(true);
}
break;
}
return super.onTouchEvent(evt);
}
}
- 至此,就可以使用了,把我们代码中的PieChart都替换成MyPieChart就好了,赶紧试试吧,看有没有达到去除重叠的效果。
网友评论