图中的不规则阴影 [英] Irregular shading in Graph

查看:198
本文介绍了图中的不规则阴影的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图复制我在网络中找到的圆环图代码。代码如下

I tried to replicate a donut chart code that I found in the net. The code is as follows

public class DonutChart extends View{

private float radius;
SharedPreferences prefs;
Paint paint;
Paint shadowPaint;
int a,b,c;
Path myPath;
Path shadowPath;

RectF outterCircle;
RectF innerCircle;
RectF shadowRectF;
public DonutChart(Context context, AttributeSet attrs) {
    super(context, attrs);

    TypedArray a = context.getTheme().obtainStyledAttributes(
            attrs,
            R.styleable.DonutChart,
            0, 0
    );

    try {
        radius = a.getDimension(R.styleable.DonutChart_radius, 20.0f);
    } finally {
        a.recycle();
    }

    paint = new Paint();
    paint.setDither(true);
    paint.setStyle(Paint.Style.FILL);
    paint.setStrokeJoin(Paint.Join.ROUND);
    paint.setStrokeCap(Paint.Cap.ROUND);
    paint.setAntiAlias(true);
    paint.setStrokeWidth(radius / 14.0f);

    shadowPaint = new Paint();
    shadowPaint.setColor(0xf0000000);
    shadowPaint.setStyle(Paint.Style.STROKE);
    shadowPaint.setAntiAlias(true);
    shadowPaint.setStrokeWidth(6.0f);
    shadowPaint.setMaskFilter(new BlurMaskFilter(4, BlurMaskFilter.Blur.SOLID));


    myPath = new Path();
    shadowPath = new Path();


    outterCircle = new RectF();
    innerCircle = new RectF();
    shadowRectF = new RectF();

    float adjust = (.019f*radius);
    shadowRectF.set(adjust, adjust, radius*2-adjust, radius*2-adjust);

    adjust = .038f * radius;
    outterCircle.set(adjust, adjust, radius*2-adjust, radius*2-adjust);

    adjust = .276f * radius;
    innerCircle.set(adjust, adjust, radius * 2 - adjust, radius * 2 - adjust);
}
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    // draw shadow

    paint.setShader(null);
    float adjust = (.0095f*radius);
    paint.setShadowLayer(8, adjust, -adjust, 0xaa000000);
    drawDonut(canvas, paint, 0, 359.9f);
    //Orange
    setGradient(0xffEF6632,0xffEF6632);
    drawDonut(canvas,paint, 0,b);
    //Blue
    setGradient(0xff00CCDA,0xff00CCDA);
    drawDonut(canvas, paint, 60,a);
    // blue
//    setGradient(0xff4AB6C1,0xff2182AD);
//    drawDonut(canvas, paint, 120, 60);
    // Grey
    setGradient(0xff557687,0xff557687);
    drawDonut(canvas, paint, 180,c);
}
public void drawDonut(Canvas canvas, Paint paint, float start,float sweep){

    myPath.reset();
    myPath.arcTo(outterCircle, start, sweep, false);
    myPath.arcTo(innerCircle, start+sweep, -sweep, false);
    myPath.close();
    canvas.drawPath(myPath, paint);
}

public void setGradient(int sColor, int eColor){
    paint.setShader(new RadialGradient(radius, radius, radius - 5,
            new int[]{sColor, eColor},
            new float[]{.6f, .95f}, TileMode.CLAMP));
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
    super.onMeasure(widthMeasureSpec, heightMeasureSpec);

    int desiredWidth = (int) radius*2;
    int desiredHeight = (int) radius*2;

    int widthMode = MeasureSpec.getMode(widthMeasureSpec);
    int widthSize = MeasureSpec.getSize(widthMeasureSpec);
    int heightMode = MeasureSpec.getMode(heightMeasureSpec);
    int heightSize = MeasureSpec.getSize(heightMeasureSpec);

    int width;
    int height;

    //70dp exact
    if (widthMode == MeasureSpec.EXACTLY) {
        width = widthSize;
    }else if (widthMode == MeasureSpec.AT_MOST) {
        //wrap content
        width = Math.min(desiredWidth, widthSize);
    } else {
        width = desiredWidth;
    }

    //Measure Height
    if (heightMode == MeasureSpec.EXACTLY) {
        height = heightSize;
    } else if (heightMode == MeasureSpec.AT_MOST) {
        height = Math.min(desiredHeight, heightSize);
    } else {
        height = desiredHeight;
    }

    //MUST CALL THIS
    setMeasuredDimension(width, height);
}
public void getData(int x,int y){
    invalidate();
    a=((x*360)/10);
    b=(y*360)/10;
    c=((10-(x+y))*360)/10;
    String s1,s2,s3;
    s1=String.valueOf(a);
    s2=String.valueOf(b);
    s3=String.valueOf(c);
    Toast.makeText(getContext(),"Inside Chart "+s1+" "+s2+" "+s3 +" "+String.valueOf(x),Toast.LENGTH_SHORT).show();
}

}

问题是当我渲染在我的设备上的图形,它给我一个奇怪的阴影,像这样:

The problem is when I render the graph on my device it gives me a weird shadow like this:

或像这样:

是什么原因以及如何纠正它?

What is causing this and how to rectify it?

推荐答案

这实际上是由于只改变线长度的值,而起始点是相同的,所以有时它们往往会重叠。

This is actually caused because only the value of the line length is changed whereas the starting point is the same so sometimes they tend to overlap.

这可以通过修改代码来解决,如下所示:

This can be solved by changing the code as follows

protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// draw shadow
paint.setShader(null);
float adjust = (.0095f*radius);
paint.setShadowLayer(8, adjust, -adjust, 0xaa000000);
drawDonut(canvas, paint, 0, 359.9f);
//Orange
setGradient(0xffEF6632,0xffEF6632);
drawDonut(canvas,paint, 0,b);
//Blue
setGradient(0xff00CCDA,0xff00CCDA);
drawDonut(canvas, paint, b,a);
// Grey
setGradient(0xff557687,0xff557687);
drawDonut(canvas, paint, a+b,c);
} 

这篇关于图中的不规则阴影的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆