MPAndroidChart - 如何在 LimitLine 左侧显示文本?

DIR*_*AVE 5 android mpandroidchart

我试图在 LimitLine 左侧显示文本,如下所示:

在此输入图像描述

然而,这些是我设置Label限制线位置的唯一选项。

在此输入图像描述

我正在使用LimitLine.LimitLabelPosition.LEFT_TOP,它只显示Label限制线上方的内容。

在此输入图像描述

YAxis leftAxis = mChart.getAxisLeft();
LimitLine minimumLimit = new LimitLine(50f, "Minimum Limit");
minimumLimit.setLineWidth(0.5f);
minimumLimit.setTextColor(ContextCompat.getColor(this, R.color.white_60_opacity));
minimumLimit.setLabelPosition(LimitLine.LimitLabelPosition.LEFT_TOP);
leftAxis.addLimitLine(minimumLimit);
Run Code Online (Sandbox Code Playgroud)

如何LimitLine在 的左侧显示 的标签LimitLine

编辑:

我也尝试过使用这些方法.setXOffset(50f).setYOffset(50f)但这只会改变标签的位置,而不改变线条的位置minimumLimit

在此输入图像描述

Mar*_*osP 3

您可以通过使用自定义YAxisRenderer并稍微修改覆盖方法来实现此目的public void renderLimitLines(Canvas c)

为此目的所需的修改是:

1 .计算每条限制线的标签宽度,以便能够将限制线移动到正确的x位置,如下所示:

limitLinePath.moveTo(mViewPortHandler.contentLeft()+getLabelTextWidth(l), pts[1]);
Run Code Online (Sandbox Code Playgroud)

2.将标签绘制到新的 x,y 位置,如下所示:

c.drawText(label, mViewPortHandler.contentLeft() + xOffset, pts[1]+l.getYOffset(), mLimitLinePaint);
Run Code Online (Sandbox Code Playgroud)

MyYAxisRenderer以下是包含上述修改的自定义:

public class MyYAxisRenderer extends YAxisRenderer {

    private final Paint textPaint;

    public MyYAxisRenderer(ViewPortHandler viewPortHandler, YAxis yAxis, Transformer trans) {
        super(viewPortHandler, yAxis, trans);
        textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
    }

    @Override
    public void renderLimitLines(Canvas c) {

        List<LimitLine> limitLines = mYAxis.getLimitLines();

        if (limitLines == null || limitLines.size() <= 0)
            return;

        float[] pts = mRenderLimitLinesBuffer;
        pts[0] = 0;
        pts[1] = 0;
        Path limitLinePath = mRenderLimitLines;
        limitLinePath.reset();

        for (int i = 0; i < limitLines.size(); i++) {

            LimitLine l = limitLines.get(i);

            if (!l.isEnabled())
                continue;

            int clipRestoreCount = c.save();
            mLimitLineClippingRect.set(mViewPortHandler.getContentRect());
            mLimitLineClippingRect.inset(0.f, -l.getLineWidth());
            c.clipRect(mLimitLineClippingRect);

            mLimitLinePaint.setStyle(Paint.Style.STROKE);
            mLimitLinePaint.setColor(l.getLineColor());
            mLimitLinePaint.setStrokeWidth(l.getLineWidth());
            mLimitLinePaint.setPathEffect(l.getDashPathEffect());

            pts[1] = l.getLimit();

            mTrans.pointValuesToPixel(pts);

            limitLinePath.moveTo(mViewPortHandler.contentLeft()+getLabelTextWidth(l), pts[1]);
            limitLinePath.lineTo(mViewPortHandler.contentRight(), pts[1]);

            c.drawPath(limitLinePath, mLimitLinePaint);
            limitLinePath.reset();

            String label = l.getLabel();

            // if drawing the limit-value label is enabled
            if (label != null && !label.equals("")) {

                mLimitLinePaint.setStyle(l.getTextStyle());
                mLimitLinePaint.setPathEffect(null);
                mLimitLinePaint.setColor(l.getTextColor());
                mLimitLinePaint.setTypeface(l.getTypeface());
                mLimitLinePaint.setStrokeWidth(0.5f);
                mLimitLinePaint.setTextSize(l.getTextSize());

                final float labelLineHeight = Utils.calcTextHeight(mLimitLinePaint, label);
                float xOffset = getLimitLineXOffset(l);
                float yOffset = l.getLineWidth() + labelLineHeight + l.getYOffset();

                final LimitLine.LimitLabelPosition position = l.getLabelPosition();

                //draw the label on the left in the same y position of the limit line
                mLimitLinePaint.setTextAlign(Paint.Align.LEFT);
                c.drawText(label,
                        mViewPortHandler.contentLeft() + xOffset,
                        pts[1]+l.getYOffset(), mLimitLinePaint);
            }

            c.restoreToCount(clipRestoreCount);
        }
    }

    private float getLimitLineXOffset(LimitLine l){
        return Utils.convertDpToPixel(4f) + l.getXOffset();
    }

    private float getLabelTextWidth(LimitLine l) {

        String label = l.getLabel();
        if (label != null && !label.equals("")) {

            textPaint.setStyle(l.getTextStyle());
            textPaint.setPathEffect(null);
            textPaint.setColor(l.getTextColor());
            textPaint.setTypeface(l.getTypeface());
            textPaint.setStrokeWidth(0.5f);
            textPaint.setTextSize(l.getTextSize());

            int textWidth = Utils.calcTextWidth(textPaint, label);
            float xOffset = getLimitLineXOffset(l);

            return textWidth + (xOffset*2);
        }
        return 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

在上面的渲染器中,我添加了两个辅助函数,一个用于计算private float getLabelTextWidth(LimitLine l)特定限制线的标签文本宽度,另一个用于获取每个私有限制线的 x 偏移量float getLimitLineXOffset(LimitLine l),您可以根据需要进行修改。

您可以像下面这样使用上面的渲染器:

lineChart.setRendererLeftYAxis(new MyYAxisRenderer(lineChart.getViewPortHandler(), lineChart.getAxisLeft(), lineChart.getTransformer(YAxis.AxisDependency.LEFT)));
Run Code Online (Sandbox Code Playgroud)

结果:

限制线

注意:这是使用 v3.1.0 进行测试的('com.github.PhilJay:MPAndroidChart:v3.1.0')