Skip to content

Highlight issues after i applied RoundedSlicesPieChartRenderer in piechart #5432

Open
@GopalAlliance

Description

@GopalAlliance

Summary
I have applied RoundedSlicesPieChartRenderer to pie chart to have round corner it worked but the highlight function is not working when i remove the RoundedSlicesPieChartRenderer the highligh works but when i remove it it doesn't.
this is the code


public class RoundedSlicesPieChartRenderer extends PieChartRenderer {
    public RoundedSlicesPieChartRenderer(PieChart chart, ChartAnimator animator, ViewPortHandler viewPortHandler) {
        super(chart, animator, viewPortHandler);
        chart.setDrawRoundedSlices(true);
    }
    @Override
    protected void drawDataSet(Canvas c, IPieDataSet dataSet) {
        float angle = 0;
        float rotationAngle = mChart.getRotationAngle();

        float phaseX = mAnimator.getPhaseX();
        float phaseY = mAnimator.getPhaseY();

        final RectF circleBox = mChart.getCircleBox();

        final int entryCount = dataSet.getEntryCount();
        final float[] drawAngles = mChart.getDrawAngles();
        final MPPointF center = mChart.getCenterCircleBox();
        final float radius = mChart.getRadius();
        final boolean drawInnerArc = mChart.isDrawHoleEnabled() && !mChart.isDrawSlicesUnderHoleEnabled();
        final float userInnerRadius = drawInnerArc
                ? radius * (mChart.getHoleRadius() / 100.f)
                : 0.f;
        final float roundedRadius = (radius - (radius * mChart.getHoleRadius() / 100f)) / 2f;
        final RectF roundedCircleBox = new RectF();

        int visibleAngleCount = 0;
        for (int j = 0; j < entryCount; j++) {
            // draw only if the value is greater than zero
            if ((Math.abs(dataSet.getEntryForIndex(j).getY()) > Utils.FLOAT_EPSILON)) {
                visibleAngleCount++;
            }
        }

        final float sliceSpace = visibleAngleCount <= 1 ? 0.f : getSliceSpace(dataSet);
        final Path pathBuffer = new Path();
        final RectF mInnerRectBuffer = new RectF();

        for (int j = 0; j < entryCount; j++) {
            float sliceAngle = drawAngles[j];
            float innerRadius = userInnerRadius;

            Entry e = dataSet.getEntryForIndex(j);

            // draw only if the value is greater than zero
            if (!(Math.abs(e.getY()) > Utils.FLOAT_EPSILON)) {
                angle += sliceAngle * phaseX;
                continue;
            }

            // Don't draw if it's highlighted, unless the chart uses rounded slices
            if (mChart.needsHighlight(j) && !drawInnerArc) {
                angle += sliceAngle * phaseX;
                continue;
            }

            final boolean accountForSliceSpacing = sliceSpace > 0.f && sliceAngle <= 180.f;

            mRenderPaint.setColor(dataSet.getColor(j));

            final float sliceSpaceAngleOuter = visibleAngleCount == 1 ?
                    0.f :
                    sliceSpace / (Utils.FDEG2RAD * radius);
            final float startAngleOuter = rotationAngle + (angle + sliceSpaceAngleOuter / 2.f) * phaseY;
            float sweepAngleOuter = (sliceAngle - sliceSpaceAngleOuter) * phaseY;

            if (sweepAngleOuter < 0.f) {
                sweepAngleOuter = 0.f;
            }

            pathBuffer.reset();

            float arcStartPointX = center.x + radius * (float) Math.cos(startAngleOuter * Utils.FDEG2RAD);
            float arcStartPointY = center.y + radius * (float) Math.sin(startAngleOuter * Utils.FDEG2RAD);

            if (sweepAngleOuter >= 360.f && sweepAngleOuter % 360f <= Utils.FLOAT_EPSILON) {
                // Android is doing "mod 360"
                pathBuffer.addCircle(center.x, center.y, radius, Path.Direction.CW);
            } else {
                if (drawInnerArc) {
                    float x = center.x + (radius - roundedRadius) * (float) Math.cos(startAngleOuter * Utils.FDEG2RAD);
                    float y = center.y + (radius - roundedRadius) * (float) Math.sin(startAngleOuter * Utils.FDEG2RAD);

                    roundedCircleBox.set(x - roundedRadius, y - roundedRadius, x + roundedRadius, y + roundedRadius);
                    pathBuffer.arcTo(roundedCircleBox, startAngleOuter - 180, 180);
                }

                pathBuffer.arcTo(
                        circleBox,
                        startAngleOuter,
                        sweepAngleOuter
                );
            }

            // API < 21 does not receive floats in addArc, but a RectF
            mInnerRectBuffer.set(
                    center.x - innerRadius,
                    center.y - innerRadius,
                    center.x + innerRadius,
                    center.y + innerRadius);

            if (drawInnerArc && (innerRadius > 0.f || accountForSliceSpacing)) {

                if (accountForSliceSpacing) {
                    float minSpacedRadius =
                            calculateMinimumRadiusForSpacedSlice(
                                    center, radius,
                                    sliceAngle * phaseY,
                                    arcStartPointX, arcStartPointY,
                                    startAngleOuter,
                                    sweepAngleOuter);

                    if (minSpacedRadius < 0.f)
                        minSpacedRadius = -minSpacedRadius;

                    innerRadius = Math.max(innerRadius, minSpacedRadius);
                }

                final float sliceSpaceAngleInner = visibleAngleCount == 1 || innerRadius == 0.f ?
                        0.f :
                        sliceSpace / (Utils.FDEG2RAD * innerRadius);
                final float startAngleInner = rotationAngle + (angle + sliceSpaceAngleInner / 2.f) * phaseY;
                float sweepAngleInner = (sliceAngle - sliceSpaceAngleInner) * phaseY;
                if (sweepAngleInner < 0.f) {
                    sweepAngleInner = 0.f;
                }
                final float endAngleInner = startAngleInner + sweepAngleInner;

                if (sweepAngleOuter >= 360.f && sweepAngleOuter % 360f <= Utils.FLOAT_EPSILON) {
                    // Android is doing "mod 360"
                    pathBuffer.addCircle(center.x, center.y, innerRadius, Path.Direction.CCW);
                } else {
                    float x = center.x + (radius - roundedRadius) * (float) Math.cos(endAngleInner * Utils.FDEG2RAD);
                    float y = center.y + (radius - roundedRadius) * (float) Math.sin(endAngleInner * Utils.FDEG2RAD);

                    roundedCircleBox.set(x - roundedRadius, y - roundedRadius, x + roundedRadius, y + roundedRadius);

                    pathBuffer.arcTo(roundedCircleBox, endAngleInner, 180);
                    pathBuffer.arcTo(mInnerRectBuffer, endAngleInner, -sweepAngleInner);
                }
            } else {

                if (sweepAngleOuter % 360f > Utils.FLOAT_EPSILON) {
                    if (accountForSliceSpacing) {

                        float angleMiddle = startAngleOuter + sweepAngleOuter / 2.f;

                        float sliceSpaceOffset =
                                calculateMinimumRadiusForSpacedSlice(
                                        center,
                                        radius,
                                        sliceAngle * phaseY,
                                        arcStartPointX,
                                        arcStartPointY,
                                        startAngleOuter,
                                        sweepAngleOuter);

                        float arcEndPointX = center.x +
                                sliceSpaceOffset * (float) Math.cos(angleMiddle * Utils.FDEG2RAD);
                        float arcEndPointY = center.y +
                                sliceSpaceOffset * (float) Math.sin(angleMiddle * Utils.FDEG2RAD);

                        pathBuffer.lineTo(
                                arcEndPointX,
                                arcEndPointY);

                    } else {
                        pathBuffer.lineTo(
                                center.x,
                                center.y);
                    }
                }

            }

            pathBuffer.close();

            mBitmapCanvas.drawPath(pathBuffer, mRenderPaint);

            angle += sliceAngle * phaseX;
        }

        MPPointF.recycleInstance(center);
    }
}

this is how i applied round corner in my pie chart this is just a demo code.
_binding.pieChartMikePhil.setUsePercentValues(true)

    _binding.pieChartMikePhil.description.isEnabled = false

    _binding.pieChartMikePhil.dragDecelerationFrictionCoef = 0.95f

    _binding.pieChartMikePhil.isDrawHoleEnabled = true
    _binding.pieChartMikePhil.renderer = RoundedSlicesPieChartRenderer(
        _binding.pieChartMikePhil,
        _binding.pieChartMikePhil.animator,
        _binding.pieChartMikePhil.viewPortHandler
    )
    _binding.pieChartMikePhil.setHoleColor(resources.getColor(android.R.color.transparent))

    _binding.pieChartMikePhil.setTransparentCircleColor(resources.getColor(android.R.color.transparent))
    _binding.pieChartMikePhil.setTransparentCircleAlpha(110)

    _binding.pieChartMikePhil.holeRadius = 82f
    _binding.pieChartMikePhil.transparentCircleRadius = 61f
    _binding.pieChartMikePhil.setDrawCenterText(true)
    _binding.pieChartMikePhil.rotationAngle = 0f
    _binding.pieChartMikePhil.isRotationEnabled = true
    _binding.pieChartMikePhil.isHighlightPerTapEnabled = true
    _binding.pieChartMikePhil.animateY(1400, Easing.EaseInOutQuad)

    _binding.pieChartMikePhil.legend.isEnabled = false
    val colors: ArrayList<Int> = ArrayList()

    val entries: ArrayList<PieEntry> = ArrayList()
    entries.add(PieEntry(100f, ""))
    colors.add(resources.getColor((R.color.noDataColor)))
    _binding.totalAmount.visibility = View.GONE
    _binding.categoryName.text = "No Data found"
    val dataSet = PieDataSet(entries, "Mobile OS")
    dataSet.sliceSpace = 5f
    dataSet.selectionShift = 15f

    dataSet.colors = colors


    // set this to false to disable the drawing of highlight indicator (lines)


    val datas = PieData(dataSet)
    datas.setValueFormatter(PercentFormatter())
    datas.setValueTypeface(Typeface.DEFAULT_BOLD)
    datas.setValueTextColor(resources.getColor(android.R.color.transparent))
    _binding.pieChartMikePhil.data = datas
    _binding.pieChartMikePhil.highlightValues(null)
    _binding.pieChartMikePhil.highlightValue(null)
    _binding.pieChartMikePhil.invalidate()
    _binding.pieChartMikePhil.setDrawSliceText(false)

Expected Behavior
the slice should pop out/ highlighted / the height of the slice should be increased when click on it.

Device (please complete the following information):
In every device

Additional Context
image
expected
image

ADD A REWARD using Speed to SOLVE this issue QUICKLY and SUPPORT this project.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions