目录
1 思路:
2 实现:
3 效果:
查看RadarChart控件源码,找到绘制网线的相关源码,获取到各个顶点的坐标后,便可以在各个顶点绘制圆。
Step 1:既然圆点是在网线各个顶点,那便跟绘制网线相关联,我们可以从绘制网线的公开方法入手去查找,最先想到就是setDrawWeb方法,直接影响网线的绘制,这个方法也很简单只设置了mDrawWeb的值。
Step 2:接下来我们要查找变量mDrawWeb在绘制中的实际已应用,绘制便跟onDraw方法有关。可以看出绘制网线时,调用了mRenderer变量的drawExtras(canvas)。
Step 3:查找mRenderer变量的具体对象。
Step 4:查找RadarChartRenderer对象中drawExtras(canvas)方法到底做了什么事情。
Step 5:drawExtras(canvas)方法中如下这段代码是绘制每段网线的,从中可以获取到各个顶点的坐标。
Step 6:通过该坐标在里面进行圆点的绘制,由于我们无法直接编辑源码,我们还需要重写RadarChart和RadarChartRenderer这两个类。
Step 1:新建我们自己的RadarChartRenderer类继承RadarChartRenderer,重写drawWeb(Canvas c)方法,里面内容直接拷贝原方法代码后在指定加上如下这段代码。
for (int j = 0; j < labelCount; j++) {
for (int i = 0; i < mChart.getData().getEntryCount(); i++) {
float r = (mChart.getYAxis().mEntries[j] - mChart.getYChartMin()) * factor;
Utils.getPosition(center, r, sliceangle * i + rotationangle, p1out);
Utils.getPosition(center, r, sliceangle * (i + 1) + rotationangle, p2out);
c.drawLine(p1out.x, p1out.y, p2out.x, p2out.y, mWebPaint);
// start(加上下面这几行代码,用于绘制每个顶角上的圆)
if (mDrawAngleCircle && j == labelCount - 1) {
mAngleCirclePaint.setColor(mAngleCircleColors == null || mAngleCircleColors.length == 0 ? Color.BLACK : this.mAngleCircleColors[i % mAngleCircleColors.length]);
c.drawCircle(p2out.x, p2out.y, mAngleCircleRadius, mAngleCirclePaint);
}
// end
}
}
完整代码:
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import com.github.mikephil.charting.animation.ChartAnimator;
import com.github.mikephil.charting.charts.RadarChart;
import com.github.mikephil.charting.utils.MPPointF;
import com.github.mikephil.charting.utils.Utils;
import com.github.mikephil.charting.utils.ViewPortHandler;
public class RadarChartRenderer extends com.github.mikephil.charting.renderer.RadarChartRenderer {
private Paint mAngleCirclePaint;
private float mAngleCircleRadius = Utils.convertDpToPixel(5f);
private int[] mAngleCircleColors;
private boolean mDrawAngleCircle = false;
public RadarChartRenderer(RadarChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
super(chart, animator, viewPortHandler);
mAngleCirclePaint = new Paint();
}
@Override
protected void drawWeb(Canvas c) {
float sliceangle = mChart.getSliceAngle();
// calculate the factor that is needed for transforming the value to
// pixels
float factor = mChart.getFactor();
float rotationangle = mChart.getRotationAngle();
MPPointF center = mChart.getCenterOffsets();
// draw the web lines that come from the center
mWebPaint.setStrokeWidth(mChart.getWebLineWidth());
mWebPaint.setColor(mChart.getWebColor());
mWebPaint.setAlpha(mChart.getWebAlpha());
final int xIncrements = 1 + mChart.getSkipWebLineCount();
int maxEntryCount = mChart.getData().getMaxEntryCountSet().getEntryCount();
MPPointF p = MPPointF.getInstance(0,0);
for (int i = 0; i < maxEntryCount; i += xIncrements) {
Utils.getPosition(
center,
mChart.getYRange() * factor,
sliceangle * i + rotationangle,
p);
c.drawLine(center.x, center.y, p.x, p.y, mWebPaint);
}
MPPointF.recycleInstance(p);
// draw the inner-web
mWebPaint.setStrokeWidth(mChart.getWebLineWidthInner());
mWebPaint.setColor(mChart.getWebColorInner());
mWebPaint.setAlpha(mChart.getWebAlpha());
int labelCount = mChart.getYAxis().mEntryCount;
MPPointF p1out = MPPointF.getInstance(0,0);
MPPointF p2out = MPPointF.getInstance(0,0);
for (int j = 0; j < labelCount; j++) {
for (int i = 0; i < mChart.getData().getEntryCount(); i++) {
float r = (mChart.getYAxis().mEntries[j] - mChart.getYChartMin()) * factor;
Utils.getPosition(center, r, sliceangle * i + rotationangle, p1out);
Utils.getPosition(center, r, sliceangle * (i + 1) + rotationangle, p2out);
c.drawLine(p1out.x, p1out.y, p2out.x, p2out.y, mWebPaint);
// start(加上下面这几行代码,用于绘制每个顶角上的圆)
if (mDrawAngleCircle && j == labelCount - 1) {
mAngleCirclePaint.setColor(mAngleCircleColors == null || mAngleCircleColors.length == 0 ? Color.BLACK : this.mAngleCircleColors[i % mAngleCircleColors.length]);
c.drawCircle(p2out.x, p2out.y, mAngleCircleRadius, mAngleCirclePaint);
}
// end
}
}
MPPointF.recycleInstance(p1out);
MPPointF.recycleInstance(p2out);
}
/**
* 顶角圆点颜色
* @param colors 颜色
*/
public void setAngleCircleColor(int[] colors) {
this.mAngleCircleColors = colors;
}
/**
* 顶角圆点半径
* @param radius 半径
*/
public void setAngleCircleRadius(float radius) {
this.mAngleCircleRadius = Utils.convertDpToPixel(radius);
}
/**
* 是否绘制顶角圆点
* @param draw
*/
public void setDrawAngleCircle(boolean draw) {
this.mDrawAngleCircle = draw;
}
}
Step 2:新建我们自己的RadarChart类继承RadarChart,重写init()方法。
@Override
protected void init() {
super.init();
this.mRenderer = new RadarChartRenderer(this, mAnimator, mViewPortHandler);
}
完整代码:
import android.content.Context;
import android.util.AttributeSet;
public class RadarChart extends com.github.mikephil.charting.charts.RadarChart {
public RadarChart(Context context) {
super(context);
}
public RadarChart(Context context, AttributeSet attrs) {
super(context, attrs);
}
public RadarChart(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void init() {
super.init();
this.mRenderer = new RadarChartRenderer(this, mAnimator, mViewPortHandler);
}
/**
* 是否绘制顶角圆点
* @param draw
*/
public void setDrawAngleCircle(boolean draw) {
((RadarChartRenderer) this.mRenderer).setDrawAngleCircle(draw);
}
/**
* 顶角圆点颜色
* @param colors 颜色
*/
public void setAngleCircleColor(int[] colors) {
((RadarChartRenderer) this.mRenderer).setAngleCircleColor(colors);
}
/**
* 顶角圆点半径
* @param radius 半径
*/
public void setAngleCircleRadius(float radius) {
((RadarChartRenderer) this.mRenderer).setAngleCircleRadius(radius);
}
}
Step 3:在界面中,使用我们自己RadarChart,再开启绘制顶点圆点,设置颜色。
rc.setDrawAngleCircle(true);
rc.setAngleCircleColor(new int[] {
Color.parseColor("#36a9ce"),
Color.parseColor("#33ff66"),
Color.parseColor("#ef5aa1"),
Color.parseColor("#ff0000"),
Color.parseColor("#6600ff")
});
雷达图的使用教程:https://blog.csdn.net/Honiler/article/details/90407390