BArtWell
BArtWell

Reputation: 4044

MPAndroidChart: How to show circles on all lines on click?

I am showing several LineDataSet in my chart. I don't need to show circles by default. But when user clicks a chart I need to show circles on all lines depending x value. How to implement it?

enter image description here

Upvotes: 1

Views: 1995

Answers (2)

Dhvani023
Dhvani023

Reputation: 1207

Below code is my solution: (it should edit the library source code,so pls import as module)

1. in LineChartRenderer class

       private final Paint mHighlightPointStokePaint = new Paint();
       private final Paint mHighlightPointInnerPaint = new Paint();

       @Override
       public void drawHighlighted(Canvas c, Highlight[] indices) {

        LineData lineData = mChart.getLineData();
        int entryIndex = -1;

        for (Highlight high : indices) {

            ILineDataSet set = lineData.getDataSetByIndex(high.getDataSetIndex());

            if (set == null || !set.isHighlightEnabled())
                continue;

            Entry e = set.getEntryForXValue(high.getX(), high.getY());

            if (!isInBoundsX(e, set))
                continue;

            entryIndex = set.getEntryIndex(e);
            MPPointD pix = mChart.getTransformer(set.getAxisDependency()).getPixelForValues(e.getX(), e.getY() * mAnimator
                    .getPhaseY());

            high.setDraw((float) pix.x, (float) pix.y);

            // draw the lines
            drawHighlightLines(c, (float) pix.x, (float) pix.y, set);
        }

        if (entryIndex < 0) {
            return;
        }

        if (mChart instanceof BarLineChartBase) {
            BarLineChartBase chart = (BarLineChartBase) this.mChart;
            if (chart.isDrawHighlightPoint()) {
                mHighlightPointInnerPaint.reset();
                mHighlightPointInnerPaint.setAntiAlias(true);
                mHighlightPointInnerPaint.setStyle(Paint.Style.FILL);

                //交点外圈白环
                mHighlightPointStokePaint.reset();
                mHighlightPointStokePaint.setAntiAlias(true);
                mHighlightPointStokePaint.setStyle(Paint.Style.STROKE);
                mHighlightPointStokePaint.setStrokeWidth(chart.getHighLightPointStrokeWidth());
                mHighlightPointStokePaint.setColor(Color.WHITE);

                List<ILineDataSet> dataSets = lineData.getDataSets();
                for (ILineDataSet set : dataSets) {
                    if (entryIndex < set.getEntryCount()) {
                        Entry e = set.getEntryForIndex(entryIndex);
                        MPPointD pix = mChart.getTransformer(set.getAxisDependency())
                                .getPixelForValues(e.getX(), e.getY() * mAnimator.getPhaseY());

                        drawHighlightPoint(c, (float) pix.x, (float) pix.y, chart, set);
                    }
                }
            }
        }
       }

        private void drawHighlightPoint(Canvas c, float x, float y, BarLineChartBase chart, ILineDataSet set) {
        //点内圆的颜色和图表线条一致,且将颜色的不透明度调满!
        mHighlightPointInnerPaint.setColor(((255) << 24) | set.getColor());
        //绘制内圆
        c.drawCircle(x, y, chart.getHighLightPointInnerRadius(), mHighlightPointInnerPaint);
        //绘制外圆
        c.drawCircle(x, y, chart.getHighLightPointInnerRadius(), mHighlightPointStokePaint);
       }

2. in BarLineChartBase class

       /**
       * flag that indicates if draw highlight point is enabled or not
       */
       protected boolean isDrawHighlightPoint = false;

       /**
       * the highlight point inner radius (px)
       */
       protected int mHighLightPointInnerRadius = 1;

       /**
        * the highlight point stroke width (px)
        */
       protected int mHighLightPointStrokeWidth = 1;

       public boolean isDrawHighlightPoint() {
        return isDrawHighlightPoint;
       }
 
       public void setDrawHighlightPoint(boolean drawHighlightPoint) {
        isDrawHighlightPoint = drawHighlightPoint;
       }

       public int getHighLightPointInnerRadius() {
        return mHighLightPointInnerRadius;
       }

        public void setHighLightPointInnerRadius(int 
       mHighLightPointStrokeWidth) {
        this.mHighLightPointInnerRadius = mHighLightPointStrokeWidth;
       }

       public int getHighLightPointStrokeWidth() {
        return mHighLightPointStrokeWidth;
       }

       public void setHighLightPointStrokeWidth(int 
       mHighLightPointStrokeWidth) {
        this.mHighLightPointStrokeWidth = mHighLightPointStrokeWidth;
       }

3. apply to your chart

        lineChart.setDrawHighlightPoint(true);
        lineChart.setHighLightPointInnerRadius(Utils.dp2px(5, context));
        lineChart.setHighLightPointStrokeWidth(Utils.dp2px(3, context));

4.      public static int dp2px(Context context, float dpValue) {
         if (context == null || compareFloat(0f, dpValue) == 0) return 0;
         final float scale = 
         context.getResources().getDisplayMetrics().density;
        return (int) (dpValue * scale + 0.5f);
        }

5.      public static int compareFloat(float a, float b) {
        int ta = Math.round(a * 1000000);
        int tb = Math.round(b * 1000000);
        if (ta > tb) {
            return 1;
        } else if (ta < tb) {
            return -1;
        } else {
            return 0;
         }
        }

Upvotes: 0

Muhammad Saad Rafique
Muhammad Saad Rafique

Reputation: 3189

First you need to set draw circles false with your dataset as follows:

lineDataSet.setDrawCircles(false);

After that you need to implement OnChartGestureListener() as follows:

    lineChart.setOnChartGestureListener(new OnChartGestureListener()
    {
        @Override
        public void onChartTranslate(MotionEvent me, float dX, float dY) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onChartSingleTapped(MotionEvent me)
        {
            // TODO Auto-generated method stub
            if(lineDataSet.isDrawCirclesEnabled())
            {
                lineDataSet.setDrawCircles(false);
            }
            else
            {
                lineDataSet.setDrawCircles(true);
            }
        }

        @Override
        public void onChartScale(MotionEvent me, float scaleX, float scaleY) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onChartGestureStart(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {

        }

        @Override
        public void onChartGestureEnd(MotionEvent me, ChartTouchListener.ChartGesture lastPerformedGesture) {

        }

        @Override
        public void onChartLongPressed(MotionEvent me) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onChartFling(MotionEvent me1, MotionEvent me2,
                                 float velocityX, float velocityY) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onChartDoubleTapped(MotionEvent me) {
            // TODO Auto-generated method stub

        }
    });

This will do the job. Best of luck bro !

Upvotes: 4

Related Questions