我使用MPAndroidChart我想说明这里面CombinedChart
自定义绘制像下图:MPAndroidChart:里面的酒吧,并添加自定义图像
如果栏值> =目标价值,说,50,然后我想在栏内添加一个星形图像。
任何人都可以帮我定制BarChart吗?
我使用MPAndroidChart我想说明这里面CombinedChart
自定义绘制像下图:MPAndroidChart:里面的酒吧,并添加自定义图像
如果栏值> =目标价值,说,50,然后我想在栏内添加一个星形图像。
任何人都可以帮我定制BarChart吗?
要获得我们酒吧内的星形图像,我们需要创建一个自定义渲染器。因为我们的条形图使用BarChartRenderer
我们将继承这个第一和添加参数为我们的形象:
public class ImageBarChartRenderer extends BarChartRenderer {
private final Bitmap barImage;
public ImageBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler, Bitmap barImage) {
super(chart, animator, viewPortHandler);
this.barImage = barImage;
}
如果我们检查源BarChartRenderer
我们可以看到,它调用调用的方法drawData
,然后遍历每个数据集和请致电drawDataSet
。 drawDataSet
是动作发生的地方:它正在绘制阴影和酒吧。这是一个合适的地方加入逻辑绘制图像等额外的,所以让我们添加一个调用一个方法有引起我们的图片:
@Override
protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) {
super.drawDataSet(c, dataSet, index);
drawBarImages(c, dataSet, index);
}
我们现在需要的是将通过DataSet迭代并绘制星的方法图片。一个适当的方法将作为模板drawValues
所以让我们复制并更改它,以便绘制图像而不是文本。理解这一点的关键是看BarBuffer是如何工作的。 BarBuffer保存给定条目的条形屏幕(像素)坐标,格式为j
,j + 1
,j + 2
,j + 3
。
为了澄清,j
是左x坐标,j + 1
是最高y坐标等等,通过右边x坐标j + 3
。我们将提取这些变量,使其更易于理解:
protected void drawBarImages(Canvas c, IBarDataSet dataSet, int index) {
BarBuffer buffer = mBarBuffers[index];
float left; //avoid allocation inside loop
float right;
float top;
float bottom;
for (int j = 0; j < buffer.buffer.length * mAnimator.getPhaseX(); j += 4) {
left = buffer.buffer[j];
right = buffer.buffer[j + 2];
top = buffer.buffer[j + 1];
bottom = buffer.buffer[j + 3];
float x = (left + right)/2f;
if (!mViewPortHandler.isInBoundsRight(x))
break;
if (!mViewPortHandler.isInBoundsY(top)
|| !mViewPortHandler.isInBoundsLeft(x))
continue;
BarEntry entry = dataSet.getEntryForIndex(j/4);
float val = entry.getY();
if (val > 50) {
drawStar(c, barImage, x, top);
}
}
}
下面是如何消费的渲染:
Bitmap starBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.star);
mChart.setRenderer(new ImageBarChartRenderer(mChart, mChart.getAnimator(), mChart.getViewPortHandler(), starBitmap));
渲染器的最后一步是添加逻辑来缩放位图和正确定位。下面是自定义渲染的最终证明的概念:
package com.xxmassdeveloper.mpchartexample;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import com.github.mikephil.charting.animation.ChartAnimator;
import com.github.mikephil.charting.buffer.BarBuffer;
import com.github.mikephil.charting.data.BarEntry;
import com.github.mikephil.charting.interfaces.dataprovider.BarDataProvider;
import com.github.mikephil.charting.interfaces.datasets.IBarDataSet;
import com.github.mikephil.charting.renderer.BarChartRenderer;
import com.github.mikephil.charting.utils.ViewPortHandler;
/**
* Created by David on 29/12/2016.
*/
public class ImageBarChartRenderer extends BarChartRenderer {
private final Bitmap barImage;
public ImageBarChartRenderer(BarDataProvider chart, ChartAnimator animator, ViewPortHandler viewPortHandler, Bitmap barImage) {
super(chart, animator, viewPortHandler);
this.barImage = barImage;
}
@Override
public void drawData(Canvas c) {
super.drawData(c);
}
@Override
protected void drawDataSet(Canvas c, IBarDataSet dataSet, int index) {
super.drawDataSet(c, dataSet, index);
drawBarImages(c, dataSet, index);
}
protected void drawBarImages(Canvas c, IBarDataSet dataSet, int index) {
BarBuffer buffer = mBarBuffers[index];
float left; //avoid allocation inside loop
float right;
float top;
float bottom;
final Bitmap scaledBarImage = scaleBarImage(buffer);
int starWidth = scaledBarImage.getWidth();
int starOffset = starWidth/2;
for (int j = 0; j < buffer.buffer.length * mAnimator.getPhaseX(); j += 4) {
left = buffer.buffer[j];
right = buffer.buffer[j + 2];
top = buffer.buffer[j + 1];
bottom = buffer.buffer[j + 3];
float x = (left + right)/2f;
if (!mViewPortHandler.isInBoundsRight(x))
break;
if (!mViewPortHandler.isInBoundsY(top)
|| !mViewPortHandler.isInBoundsLeft(x))
continue;
BarEntry entry = dataSet.getEntryForIndex(j/4);
float val = entry.getY();
if (val > 50) {
drawImage(c, scaledBarImage, x - starOffset, top);
}
}
}
private Bitmap scaleBarImage(BarBuffer buffer) {
float firstLeft = buffer.buffer[0];
float firstRight = buffer.buffer[2];
int firstWidth = (int) Math.ceil(firstRight - firstLeft);
return Bitmap.createScaledBitmap(barImage, firstWidth, firstWidth, false);
}
protected void drawImage(Canvas c, Bitmap image, float x, float y) {
if (image != null) {
c.drawBitmap(image, x, y, null);
}
}
}
这里有一个屏幕截图 - 你可以看到,超过50值有星:
感谢答案。 –
不客气。 –
你在这里使用什么版本的mpandroid图表? – Amalo