Android 条形之间带有图标的饼图
Android piechart with icons between bars
我想创建一个饼图,在图例条之间包含图像。我添加下面的屏幕截图是为了更好地理解,我尝试使用一个 canvas 然后创建一个弧并尝试向其中添加图像,但它不起作用。现在我正在使用下面的饼图库来显示带有中心文本的条形图。任何建议都会有所帮助。谢谢:)
https://github.com/PhilJay/MPAndroidChart
enter image description here
此致,
罗希特·加格
您可以通过扩展 PieChartRenderer 来做到这一点。
如果您查看 PieChartRenderer.drawRoundedSlices(Canvas c)
的实现,您可以获得一个示例,说明如何获取每个切片的起始坐标。
然后只需使用 drawBitmap or drawPicture 在饼图切片之间渲染您的图像。 (我在示例中使用 Utils.drawImage
来模仿 PieChartRenderer
的来源)
例如,我复制了drawRoundedSlices
并重命名为drawImageBeforeSlice
。我没有绘制弧线,而是绘制位图。
为了让渲染器使用新方法,我覆盖了 drawExtras
并在最后调用了新方法。
class PieChartRendererWithImages extends PieChartRenderer
{
protected Drawable mImage;
public PieChartRendererWithImages(PieChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler, Drawable image) {
super(chart, animator, viewPortHandler);
mImage = image;
}
/**
* This draws an image before all pie-slices
*
* @param c
*/
protected void drawImageBeforeSlice(Canvas c) {
IPieDataSet dataSet = mChart.getData().getDataSet();
if (!dataSet.isVisible())
return;
float phaseX = mAnimator.getPhaseX();
float phaseY = mAnimator.getPhaseY();
MPPointF center = mChart.getCenterCircleBox();
float r = mChart.getRadius();
// calculate the radius of the "slice-circle"
float circleRadius = (r - (r * mChart.getHoleRadius() / 100f)) / 2f;
float[] drawAngles = mChart.getDrawAngles();
float angle = mChart.getRotationAngle();
for (int j = 0; j < dataSet.getEntryCount(); j++) {
float sliceAngle = drawAngles[j];
Entry e = dataSet.getEntryForIndex(j);
// draw only if the value is greater than zero
if ((Math.abs(e.getY()) > Utils.FLOAT_EPSILON)) {
float x = (float) ((r - circleRadius)
* Math.cos(Math.toRadians((angle + sliceAngle)
* phaseY)) + center.x);
float y = (float) ((r - circleRadius)
* Math.sin(Math.toRadians((angle + sliceAngle)
* phaseY)) + center.y);
// draw image instead of arcs
Utils.drawImage(
c,
mImage,
(int)x,
(int)y,
mImage.getIntrinsicWidth(),
mImage.getIntrinsicHeight());
}
angle += sliceAngle * phaseX;
}
MPPointF.recycleInstance(center);
}
@Override
public void drawExtras(Canvas c) {
super.drawExtras(c);
// use drawImageBeforeSlice in last step of rendering process
drawImageBeforeSlice(c);
}
}
别忘了在饼图上 set your new renderer:
myPieChart.setRenderer(new PieChartRendererWithImages(myPieChart, myPieChart.getAnimator(), myPieChart.getViewPortHandler(), getResources().getDrawable(R.drawable.my_image)));
已通过将其放入 MPAndroidChart 示例中验证其是否有效:
我想创建一个饼图,在图例条之间包含图像。我添加下面的屏幕截图是为了更好地理解,我尝试使用一个 canvas 然后创建一个弧并尝试向其中添加图像,但它不起作用。现在我正在使用下面的饼图库来显示带有中心文本的条形图。任何建议都会有所帮助。谢谢:)
https://github.com/PhilJay/MPAndroidChart
enter image description here
此致, 罗希特·加格
您可以通过扩展 PieChartRenderer 来做到这一点。
如果您查看 PieChartRenderer.drawRoundedSlices(Canvas c)
的实现,您可以获得一个示例,说明如何获取每个切片的起始坐标。
然后只需使用 drawBitmap or drawPicture 在饼图切片之间渲染您的图像。 (我在示例中使用 Utils.drawImage
来模仿 PieChartRenderer
的来源)
例如,我复制了drawRoundedSlices
并重命名为drawImageBeforeSlice
。我没有绘制弧线,而是绘制位图。
为了让渲染器使用新方法,我覆盖了 drawExtras
并在最后调用了新方法。
class PieChartRendererWithImages extends PieChartRenderer
{
protected Drawable mImage;
public PieChartRendererWithImages(PieChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler, Drawable image) {
super(chart, animator, viewPortHandler);
mImage = image;
}
/**
* This draws an image before all pie-slices
*
* @param c
*/
protected void drawImageBeforeSlice(Canvas c) {
IPieDataSet dataSet = mChart.getData().getDataSet();
if (!dataSet.isVisible())
return;
float phaseX = mAnimator.getPhaseX();
float phaseY = mAnimator.getPhaseY();
MPPointF center = mChart.getCenterCircleBox();
float r = mChart.getRadius();
// calculate the radius of the "slice-circle"
float circleRadius = (r - (r * mChart.getHoleRadius() / 100f)) / 2f;
float[] drawAngles = mChart.getDrawAngles();
float angle = mChart.getRotationAngle();
for (int j = 0; j < dataSet.getEntryCount(); j++) {
float sliceAngle = drawAngles[j];
Entry e = dataSet.getEntryForIndex(j);
// draw only if the value is greater than zero
if ((Math.abs(e.getY()) > Utils.FLOAT_EPSILON)) {
float x = (float) ((r - circleRadius)
* Math.cos(Math.toRadians((angle + sliceAngle)
* phaseY)) + center.x);
float y = (float) ((r - circleRadius)
* Math.sin(Math.toRadians((angle + sliceAngle)
* phaseY)) + center.y);
// draw image instead of arcs
Utils.drawImage(
c,
mImage,
(int)x,
(int)y,
mImage.getIntrinsicWidth(),
mImage.getIntrinsicHeight());
}
angle += sliceAngle * phaseX;
}
MPPointF.recycleInstance(center);
}
@Override
public void drawExtras(Canvas c) {
super.drawExtras(c);
// use drawImageBeforeSlice in last step of rendering process
drawImageBeforeSlice(c);
}
}
别忘了在饼图上 set your new renderer:
myPieChart.setRenderer(new PieChartRendererWithImages(myPieChart, myPieChart.getAnimator(), myPieChart.getViewPortHandler(), getResources().getDrawable(R.drawable.my_image)));
已通过将其放入 MPAndroidChart 示例中验证其是否有效: