gpt4 book ai didi

android - 点击饼图上的事件 - mpandroid

转载 作者:行者123 更新时间:2023-11-29 01:12:29 26 4
gpt4 key购买 nike

我正在使用 mpandroid 图表库。我修改了 PieChartRenderer并且能够得到这样的图表。

enter image description here

PieChartRenderer

public class ImagePieChartRenderer extends PieChartRenderer {

private ArrayList<Bitmap> bitMaps;
private Paint mEntryLabelsPaint;
public ImagePieChartRenderer(PieChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler, ArrayList<Bitmap> bitMaps) {
super(chart, animator, viewPortHandler);
this.bitMaps = bitMaps;
mEntryLabelsPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mEntryLabelsPaint.setColor(Color.BLACK);
mEntryLabelsPaint.setTextAlign(Paint.Align.CENTER);
mEntryLabelsPaint.setTextSize(Utils.convertDpToPixel(13f));
}

@Override
protected void drawDataSet(Canvas c, IPieDataSet dataSet) {
drawImages(c);
super.drawDataSet(c, dataSet);
}

private void drawImages(Canvas c) {

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;


labelRadiusOffset = (radius - (radius * holeRadiusPercent)) / 2f;


final float labelRadius = radius - labelRadiusOffset;

PieData data = mChart.getData();
List<IPieDataSet> dataSets = data.getDataSets();

float yValueSum = data.getYValueSum();

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);

// 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);

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 float valueLineLength1 = dataSet.getValueLinePart1Length();
final float valueLineLength2 = dataSet.getValueLinePart2Length();
final float valueLinePart1OffsetPercentage = dataSet.getValueLinePart1OffsetPercentage() / 100.f;

float pt2x, pt2y;
float labelPtx, labelPty;
float percentX, percentY;

float line1Radius;

line1Radius = (radius - (radius * holeRadiusPercent))
* valueLinePart1OffsetPercentage
+ (radius * holeRadiusPercent);

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;

if (transformedAngle % 360.0 >= 40.0 && transformedAngle % 360.0 <= 130.0) {
pt2x = pt1x + polyline2Width;
pt2y = pt1y;

Log.d(entry.getLabel(), "TWO "+ transformedAngle % 360.0);

mValuePaint.setTextAlign(Paint.Align.LEFT);

mEntryLabelsPaint.setTextAlign(Paint.Align.LEFT);

labelPtx = pt2x;
labelPty = pt2y;

percentX = labelPtx - 1.5f*offset ;
percentY = labelPty + bitMaps.get(j).getHeight() + 2.2f*offset;
} else {
pt2x = pt1x - polyline2Width;
pt2y = pt1y;

Log.d(entry.getLabel(), "ONE "+ transformedAngle % 360.0);

mValuePaint.setTextAlign(Paint.Align.RIGHT);

mEntryLabelsPaint.setTextAlign(Paint.Align.RIGHT);


labelPtx = pt2x;
labelPty = pt2y;

percentX = labelPtx + 1.5f*offset;
percentY = labelPty - bitMaps.get(j).getHeight() - 0.5f*offset;
}



mValueLinePaint.setColor(dataSet.getColor(j));

c.drawLine(pt0x, pt0y, pt1x, pt1y, mValueLinePaint);
c.drawLine(pt1x, pt1y, pt2x, pt2y, mValueLinePaint);


// draw everything, depending on settings



drawValue(c,
formatter,
value,
entry,
0,
percentX,
percentY,
dataSet.getValueTextColor(j));

Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(dataSet.getColor(j));
c.drawCircle(labelPtx, labelPty, bitMaps.get(j).getWidth(), paint);
c.drawBitmap(bitMaps.get(j), labelPtx-bitMaps.get(j).getWidth()/2f, labelPty-bitMaps.get(j).getHeight()/2, null );

// if (j < data.getEntryCount() && entry.getLabel() != null) {
// drawEntryLabel(c, entry.getLabel(), labelPtx, labelPty + lineHeight);
// }

xIndex++;
}
}
MPPointF.recycleInstance(center);
c.restore();
}
}

现在我需要能够点击图表周围的小圆圈。有人可以指出需要修改以实现此目的的类和函数吗?

基本上,当我触摸圆圈时,我想调用 onValueSelected(Entry e, Highlight h)

最佳答案

首先,很高兴看到人们像那样编写自己的渲染器。看起来棒极了!

对于您的实际问题,您想要的类(class)名为 OnChartGestureListener .源代码是here .

首先,您可能需要在渲染器中缓存圆圈和位图的位置。像这样:

public ImagePieChartRenderer(PieChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler, ArrayList<Bitmap> bitMaps, LabelPointCache labelPointCache) {
super(chart, animator, viewPortHandler);
this.bitMaps = bitMaps;
this.labelPointCache = labelPointCache;
mEntryLabelsPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mEntryLabelsPaint.setColor(Color.BLACK);
mEntryLabelsPaint.setTextAlign(Paint.Align.CENTER);
mEntryLabelsPaint.setTextSize(Utils.convertDpToPixel(13f));
}

//snip, then:

c.drawCircle(labelPtx, labelPty, bitMaps.get(j).getWidth(), paint);
c.drawBitmap(bitMaps.get(j), labelPtx-bitMaps.get(j).getWidth()/2f, labelPty-bitMaps.get(j).getHeight()/2, null );
//then:
float entryX = dataSet.getEntry().getX();
float entryY = dataSet.getEntry().getY();
labelPositionCache.add(entryX, entryY, labelPtx, labelPty);

现在创建一个实现该接口(interface)的类,例如 MyOnChartGestureListener。现在将其设置为您的图表:

PieChartRenderer myRenderer = new ImagePieChartRenderer(mChart, mChart.getAnimator(), mChart.getViewPortHandler(), bitmaps, labelPositionCache);
mChart.setOnChartGestureListener(new MyOnChartGestureListener(mChart, labelPointCache));

然后您需要覆盖您想要监听的 Action 事件的方法。假设您想听单击以下代码段显示了如何从原始点击的 xy 转换为图表上的图表 xValue 和 yValue:

@Override
public void onChartSingleTapped(MotionEvent me) {
float tappedX = me.getX();
float tappedY = me.getY();
MPPointD point = mChart.getTransformer(YAxis.AxisDependency.LEFT).getValuesByTouchPoint(tappedX, tappedY);
Log.d(TAG, "tapped at: " + point.x + "," + point.y);
}

您需要一些方法来检查 point.xpoint.y 是否在您的圆圈或位图中。然后你可以检查手势中的 point.xpoint.y 是否落在其中,如下所示:

if (labelPositionCache.contains(point.x, point.y)) {
float entryX = labelPositionCache.getEntryXForLabelX(point.x);
float entryY = labelPositionCache.getEntryYForLabelY(point.y);
Highlight highlight = mChart.getHighlightByTouchPoint(entryX, entryY);
mChart.highlightValues(new Highlight [] { highlight });
}

关于android - 点击饼图上的事件 - mpandroid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41967503/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com