Paint stroke not covering all the side in android

  • Replies:1
Shanmugapriyan M
  • Forum posts: 5

Apr 20, 2017, 7:20:55 AM via Website

Hi i am creating indicator for doughnut chart but it is covering only three side. Here i added onDraw method.The selected chart index arc should be highlighted with indicator.The indicator should be cover all the four sides.
image
Code:

@Override
public void draw(Canvas canvas, int x, int y, int width, int height, Paint paint) {
    paint.setAntiAlias(true);
    paint.setStyle(Style.FILL);

    int legendSize = getLegendSize(mRenderer, height / 5, 0);
    int left = x;
    int top = y;
    int right = x + width;
    int sLength = mDataset.getItemCount();
    double total = 0;
    String[] titles = new String[sLength];
    for (int i = 0; i < sLength; i++) {
        total += mDataset.getValue(i);
        titles[i] = mDataset.getCategory(i);
    }
    if (mRenderer.isFitLegend()) {
        legendSize = drawLegend(canvas, mRenderer, titles, left, right, y, width, height, legendSize, paint, true);
    }
    int bottom = y + height - legendSize;

    drawBackground(mRenderer, canvas, x, y, width, height, paint, false, Renderer.NO_COLOR);
    float currentAngle = mRenderer.getStartAngle();
    float labelCurrentAngle = mRenderer.getStartAngle();
    // int mRadius = Math.min(Math.abs(right - left), Math.abs(bottom - top));
    // int radius = (int) (500 * 0.35) + 50;
    //Log.i("radius++", "" + radius);
    int mRadius = Math.min(Math.abs(right - left), Math.abs(bottom - top));
    double rCoef = 0.35 * mRenderer.getScale();
    double decCoef = 0.2 / sLength;
    int radius = (int) (mRadius * rCoef);

    if (mCenterX == 0) {
        mCenterX = (left + right) / 2;
    }
    if (mCenterY == 0) {
        mCenterY = (bottom + top) / 2;
    }

    // Hook in clip detection after center has been calculated
    mPieMap.setDimensions(radius, mCenterX, mCenterY);
    boolean loadPieCfg = !mPieMap.areAllSegmentPresent(sLength);
    if (loadPieCfg) {
        mPieMap.clearPieSegments();
    }

    float shortRadius = radius * 0.9f;
    float longRadius = radius * 1.1f;

    RectF oval = new RectF(mCenterX - radius, mCenterY - radius, mCenterX + radius, mCenterY + radius);
    for (int i = 0; i < sLength; i++) {
        float value = (float) mDataset.getValue(i);
        float angle = (float) (value / total * 360);
        int color = mRenderer.getRenderers().get(i).getColor();

        if (mRenderer.getRenderers().get(i).isClicked()) {
            ClickedArc.CANVAS = canvas;
            ClickedArc.CURRENT_ANGLE = currentAngle;
            ClickedArc.ANGLE = angle;
            ClickedArc.COLOR = color;
            ClickedArc.INDEX = mRenderer.getRenderers().get(i).getDataIndex();
        } else {
            Paint paint3 = new Paint(Paint.ANTI_ALIAS_FLAG);
            paint3.setStrokeCap(Paint.Cap.ROUND);
            paint3.setStyle(Style.FILL);
            int[] colors = {color, color};

            RadialGradient gradient3 = new RadialGradient(mCenterX, mCenterY, radius, colors, null, android.graphics.Shader.TileMode.CLAMP);
            paint3.setShader(gradient3);
            paint3.setAntiAlias(true);

            canvas.drawArc(oval, currentAngle, angle, true, paint3);
        }

        try {
            if (mRenderer.getRenderers().get(ClickedArc.INDEX).isClicked()) {
                Paint paint3 = new Paint(Paint.ANTI_ALIAS_FLAG);
                paint3.setStyle(Style.FILL);
                paint3.setColor(Color.WHITE);

                Paint shadow = new Paint(Paint.ANTI_ALIAS_FLAG);

                int[] colors = {Color.BLACK, Color.BLACK};
                RadialGradient gradient3 = new RadialGradient(mCenterX, mCenterY, radius, colors, null, android.graphics.Shader.TileMode.CLAMP);
                shadow.setShader(gradient3);

                shadow.setAntiAlias(true);
                shadow.setColor(Color.BLACK);
                shadow.setStrokeWidth(8);
                shadow.setDither(true);
                shadow.setStyle(Paint.Style.STROKE);
                shadow.setStrokeCap(Paint.Cap.BUTT);
                shadow.setAntiAlias(true);

                int shadowRadius = radius + 2;
                RectF shadowOval = new RectF(mCenterX - shadowRadius, mCenterY - shadowRadius, mCenterX + shadowRadius, mCenterY + shadowRadius);
                canvas.drawArc(shadowOval, ClickedArc.CURRENT_ANGLE - 1, ClickedArc.ANGLE + 2, true, shadow);
                canvas.drawArc(oval, ClickedArc.CURRENT_ANGLE, ClickedArc.ANGLE, true, paint3);
            }
        } catch (IndexOutOfBoundsException e) {
            e.printStackTrace();
        }

        if (loadPieCfg) {
            mRenderer.getRenderers().get(i).setDataIndex(i);
            mPieMap.addPieSegment(i, value, currentAngle, angle + currentAngle);
        }
        currentAngle += angle;
    }

    radius -= (int) mRadius * decCoef;
    shortRadius -= mRadius * decCoef - 2;

    List<RectF> prevLabelsBounds = new ArrayList<RectF>();
    for (int i = 0; i < sLength; i++) {
        float value = (float) mDataset.getValue(i);
        float angle = (float) (value / total * 360);
        drawLabel(canvas, mDataset.getCategory(i), mRenderer, prevLabelsBounds, mCenterX, mCenterY, shortRadius / 2 + 50, longRadius / 2 + 50,
                labelCurrentAngle, angle, left, right, mRenderer.getLabelsColor(), paint, true, mRenderer.getRenderers().get(i));
        Point sPoint = mRenderer.getRenderers().get(i).getCenterPoint();
        Point ePoint = new Point((int) mRenderer.getRenderers().get(i).getTextWidth(), (int) mRenderer.getRenderers().get(i).getTextHeight());

        mPieMap.addLabelSegment(i, value, sPoint, ePoint);
        labelCurrentAngle += angle;
    }
    prevLabelsBounds.clear();
}

Reply
Mr. Jacob
  • Forum posts: 23

Apr 20, 2017, 10:13:38 PM via Website

I don't orientate well in your code at the moment, but for me it looks like you are drawing the big white circle in the center AFTER drawing the black "selected" borders, and that's why the fourth black side is missing (because the circle overlaps it). Try drawing the black borders last.

By the way, doing all of this you have in onDraw() isn't a good idea - draw method should be clean and fast to display contents, and there shouldn't be declarations inits etc.

Reply