Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Highlight issues after i applied RoundedSlicesPieChartRenderer in piechart #5432

Open
GopalAlliance opened this issue Dec 15, 2023 · 0 comments

Comments

@GopalAlliance
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant