Heisenberg
Heisenberg

Reputation: 5668

How can I draw a circle on highlight point in line chart?

I'm using mpchart to draw my charts.I wanted to increase the circle size of intersection point of highlighter and line dataset. How can I achieve this?enter image description here

I read somewhere that we can add another dataset with highlighted point and increase its circle size. Is that really a good approach if my highlighter will be dragged back and forth and I'll have to update the new dataset very frequently?

Upvotes: 7

Views: 7144

Answers (2)

Rickon Gao
Rickon Gao

Reputation: 146

I find ultimate solution.another question only can draw one point of one dataset in linechart,if I have two dataset like below,it will not draw two point。 enter image description here

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));

Upvotes: 0

Yogesh
Yogesh

Reputation: 444

When using the MpChart Library, the library contains a MarkerView class that helps us to insert the markers for displaying the selected value in the chart. We can use this MarkerView class to display any kind of view for the selected chart data.

So for the dot I created a new ChartMarker class and extended MarkerView class. Then in the constructor I passed the layout containing an image view with the dot as the src to the super.

public ChartMarker(Context context) {
    //the super will take care of displaying the layout
    super(context, R.layout.layout_dot);
}

Finally set the ChartMarker instance to the chart through chart.setMarkerView()

ChartMarker elevationMarker = new ChartMarker(getActivity());
elevationChart.setMarkerView(elevationMarker);

And for the layout_dot.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="vertical"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content">

<ImageView
    android:background="@drawable/dot"
    android:layout_width="5dp"
    android:layout_height="5dp" />

</LinearLayout>

Upvotes: 17

Related Questions