MpAndroidChart:将箭头添加到轴的末尾

发布于 2025-01-17 11:31:21 字数 696 浏览 2 评论 0原文

我想在轴线末端放置箭头,但是我不知道如何在mpandroidcharts库中实现这一目标。最后应该像这样。 crpac.png“ alt =”图表>

我当前的样式:

  val xAxis = chart.xAxis
  xAxis.setDrawLabels(false)
  xAxis.setDrawAxisLine(true)
  xAxis.setDrawGridLines(false)
  xAxis.position = XAxis.XAxisPosition.BOTTOM
  xAxis.axisLineWidth = 1.5f

  val axisLeft = chart.axisLeft
  axisLeft.setDrawGridLines(false)
  axisLeft.setDrawZeroLine(false)
  axisLeft.setDrawLabels(false)
  axisLeft.axisLineWidth = 1.5f
  axisLeft.setDrawTopYLabelEntry(true)

  val axisRight = chart.axisRight
  axisRight.setDrawGridLines(false)
  axisRight.setDrawLabels(false)
  axisRight.setDrawZeroLine(false)
  axisRight.setDrawAxisLine(false)

I would like to place an arrow at the end of the axis, but I don't know how to achieve this in MPAndroidCharts library. It should look like this at the end.Chart

My current styling:

  val xAxis = chart.xAxis
  xAxis.setDrawLabels(false)
  xAxis.setDrawAxisLine(true)
  xAxis.setDrawGridLines(false)
  xAxis.position = XAxis.XAxisPosition.BOTTOM
  xAxis.axisLineWidth = 1.5f

  val axisLeft = chart.axisLeft
  axisLeft.setDrawGridLines(false)
  axisLeft.setDrawZeroLine(false)
  axisLeft.setDrawLabels(false)
  axisLeft.axisLineWidth = 1.5f
  axisLeft.setDrawTopYLabelEntry(true)

  val axisRight = chart.axisRight
  axisRight.setDrawGridLines(false)
  axisRight.setDrawLabels(false)
  axisRight.setDrawZeroLine(false)
  axisRight.setDrawAxisLine(false)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

離殇 2025-01-24 11:31:21

要在X和Y轴的末端添加箭头,您必须制作一个自定义XaxisRendereryaxisrenderer。您要做的就是为每个渲染器制作一个子类,并覆盖公共方法renderaxisLine(C:Canvas),负责绘制轴线并通过添加添加轴线的代码并修改基本代码每个轴线末端的箭头图标。一个示例如下:

对于arrowxaxisRenderer:

class ArrowXAxisRenderer(context: Context, viewPortHandler: ViewPortHandler?, xAxis: XAxis?, trans: Transformer?)
    : XAxisRenderer(viewPortHandler, xAxis, trans) {

    private val arrowRightIcon: Drawable?
    private val arrowWidth: Int
    private val arrowHeight: Int

    init {
        arrowRightIcon = ContextCompat.getDrawable(context, R.drawable.ic_arrow_right)
        arrowWidth = arrowRightIcon!!.intrinsicWidth
        arrowHeight = arrowRightIcon.intrinsicHeight
    }

    override fun renderAxisLine(c: Canvas) {

        if (!mXAxis.isDrawAxisLineEnabled || !mXAxis.isEnabled) return

        mAxisLinePaint.color = mXAxis.axisLineColor
        mAxisLinePaint.strokeWidth = mXAxis.axisLineWidth
        mAxisLinePaint.pathEffect = mXAxis.axisLineDashPathEffect

        if (mXAxis.position == XAxis.XAxisPosition.TOP ||
            mXAxis.position == XAxis.XAxisPosition.TOP_INSIDE ||
            mXAxis.position == XAxis.XAxisPosition.BOTH_SIDED) {

            //draw the top X axis line
            c.drawLine(
                mViewPortHandler.contentLeft(),
                mViewPortHandler.contentTop(),
                mViewPortHandler.contentRight(),
                mViewPortHandler.contentTop(),
                mAxisLinePaint
            )

            //draw the arrowRightIcon on the right side of top X axis
            arrowRightIcon!!.bounds =
                Rect(
                    mViewPortHandler.contentRight().toInt() - arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() - arrowHeight / 2,
                    mViewPortHandler.contentRight().toInt() + arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() + arrowHeight / 2
                )
            arrowRightIcon.draw(c)
        }

        if (mXAxis.position == XAxis.XAxisPosition.BOTTOM ||
            mXAxis.position == XAxis.XAxisPosition.BOTTOM_INSIDE ||
            mXAxis.position == XAxis.XAxisPosition.BOTH_SIDED) {

            //draw the bottom X axis line
            c.drawLine(
                mViewPortHandler.contentLeft(),
                mViewPortHandler.contentBottom(),
                mViewPortHandler.contentRight(),
                mViewPortHandler.contentBottom(),
                mAxisLinePaint
            )

            //draw the arrowRightIcon on the right side of bottom X axis
            arrowRightIcon!!.bounds =
                Rect(
                    mViewPortHandler.contentRight().toInt() - arrowWidth / 2,
                    mViewPortHandler.contentBottom().toInt() - arrowHeight / 2,
                    mViewPortHandler.contentRight().toInt() + arrowWidth / 2,
                    mViewPortHandler.contentBottom().toInt() + arrowHeight / 2
                )
            arrowRightIcon.draw(c)
        }
    }
}

对于arrowyaxisrenderer:

class ArrowYAxisRenderer(context: Context, viewPortHandler: ViewPortHandler?, yAxis: YAxis?, trans: Transformer?)
    : YAxisRenderer(viewPortHandler, yAxis, trans) {

    private val arrowUpIcon: Drawable?
    private val arrowWidth: Int
    private val arrowHeight: Int

    init {
        arrowUpIcon = ContextCompat.getDrawable(context, R.drawable.ic_arrow_up)
        arrowWidth = arrowUpIcon!!.intrinsicWidth
        arrowHeight = arrowUpIcon.intrinsicHeight
    }

    override fun renderAxisLine(c: Canvas) {

        if (!mYAxis.isEnabled || !mYAxis.isDrawAxisLineEnabled) return

        mAxisLinePaint.color = mYAxis.axisLineColor
        mAxisLinePaint.strokeWidth = mYAxis.axisLineWidth

        if (mYAxis.axisDependency == YAxis.AxisDependency.LEFT) {

            //draw the left Y line axis
            c.drawLine(
                mViewPortHandler.contentLeft(),
                mViewPortHandler.contentTop(),
                mViewPortHandler.contentLeft(),
                mViewPortHandler.contentBottom(),
                mAxisLinePaint
            )

            //draw the arrowUp on top of the left Y axis
            arrowUpIcon!!.bounds =
                Rect(mViewPortHandler.contentLeft().toInt() - arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() - arrowHeight / 2,
                    mViewPortHandler.contentLeft().toInt() + arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() + arrowHeight / 2
                )
            arrowUpIcon.draw(c)
        }
        else {

            //draw the right Y line axis
            c.drawLine(
                mViewPortHandler.contentRight(),
                mViewPortHandler.contentTop(),
                mViewPortHandler.contentRight(),
                mViewPortHandler.contentBottom(),
                mAxisLinePaint
            )

            //draw the arrowUp on top of the right Y axis
            arrowUpIcon!!.bounds =
                Rect(
                    mViewPortHandler.contentRight().toInt() - arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() - arrowHeight / 2,
                    mViewPortHandler.contentRight().toInt() + arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() + arrowHeight / 2
                )
            arrowUpIcon.draw(c)
        }
    }
}

在上述样品中,我使用了以下矢量可言式,您可以根据自己的需求进行更改:

r.drawable.ic_arrow_right:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="@android:color/darker_gray">
    <path
        android:fillColor="@android:color/darker_gray"
        android:pathData="M8.59,16.59L13.17,12 8.59,7.41 10,6l6,6 -6,6 -1.41,-1.41z"/>
</vector>

r.drawable.ic_arrow_up:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="@android:color/darker_gray">
    <path
        android:fillColor="@android:color/darker_gray"
        android:pathData="M7.41,15.41L12,10.83l4.59,4.58L18,14l-6,-6 -6,6z"/>
</vector>

x轴的用法:

chart.setXAxisRenderer(ArrowXAxisRenderer(this, chart.getViewPortHandler(), chart.getXAxis(), chart.getTransformer(YAxis.AxisDependency.LEFT)))

y(左或右)轴的用法:

chart.setRendererLeftYAxis(ArrowYAxisRenderer(this, chart.getViewPortHandler(), chart.getAxisLeft(), chart.getTransformer(YAxis.AxisDependency.LEFT)))
chart.setRendererRightYAxis(ArrowYAxisRenderer(this, chart.getViewPortHandler(), chart.getAxisRight(), chart.getTransformer(YAxis.AxisDependency.RIGHT)))

结果:

“

注意:通过'com.github.philjay进行测试:mpandroidchart:v3.1.0'

To add an arrow on the end of X and Y axis you have to make a custom XAxisRenderer and YAxisRenderer. All you have to do is to make a subclass for each renderer and override the public method renderAxisLine(c: Canvas) which is responsible to draw the axis line and modify the code of base class by adding also the arrow icon at the end of each axis line. An example is like the below:

For ArrowXAxisRenderer:

class ArrowXAxisRenderer(context: Context, viewPortHandler: ViewPortHandler?, xAxis: XAxis?, trans: Transformer?)
    : XAxisRenderer(viewPortHandler, xAxis, trans) {

    private val arrowRightIcon: Drawable?
    private val arrowWidth: Int
    private val arrowHeight: Int

    init {
        arrowRightIcon = ContextCompat.getDrawable(context, R.drawable.ic_arrow_right)
        arrowWidth = arrowRightIcon!!.intrinsicWidth
        arrowHeight = arrowRightIcon.intrinsicHeight
    }

    override fun renderAxisLine(c: Canvas) {

        if (!mXAxis.isDrawAxisLineEnabled || !mXAxis.isEnabled) return

        mAxisLinePaint.color = mXAxis.axisLineColor
        mAxisLinePaint.strokeWidth = mXAxis.axisLineWidth
        mAxisLinePaint.pathEffect = mXAxis.axisLineDashPathEffect

        if (mXAxis.position == XAxis.XAxisPosition.TOP ||
            mXAxis.position == XAxis.XAxisPosition.TOP_INSIDE ||
            mXAxis.position == XAxis.XAxisPosition.BOTH_SIDED) {

            //draw the top X axis line
            c.drawLine(
                mViewPortHandler.contentLeft(),
                mViewPortHandler.contentTop(),
                mViewPortHandler.contentRight(),
                mViewPortHandler.contentTop(),
                mAxisLinePaint
            )

            //draw the arrowRightIcon on the right side of top X axis
            arrowRightIcon!!.bounds =
                Rect(
                    mViewPortHandler.contentRight().toInt() - arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() - arrowHeight / 2,
                    mViewPortHandler.contentRight().toInt() + arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() + arrowHeight / 2
                )
            arrowRightIcon.draw(c)
        }

        if (mXAxis.position == XAxis.XAxisPosition.BOTTOM ||
            mXAxis.position == XAxis.XAxisPosition.BOTTOM_INSIDE ||
            mXAxis.position == XAxis.XAxisPosition.BOTH_SIDED) {

            //draw the bottom X axis line
            c.drawLine(
                mViewPortHandler.contentLeft(),
                mViewPortHandler.contentBottom(),
                mViewPortHandler.contentRight(),
                mViewPortHandler.contentBottom(),
                mAxisLinePaint
            )

            //draw the arrowRightIcon on the right side of bottom X axis
            arrowRightIcon!!.bounds =
                Rect(
                    mViewPortHandler.contentRight().toInt() - arrowWidth / 2,
                    mViewPortHandler.contentBottom().toInt() - arrowHeight / 2,
                    mViewPortHandler.contentRight().toInt() + arrowWidth / 2,
                    mViewPortHandler.contentBottom().toInt() + arrowHeight / 2
                )
            arrowRightIcon.draw(c)
        }
    }
}

For ArrowYAxisRenderer:

class ArrowYAxisRenderer(context: Context, viewPortHandler: ViewPortHandler?, yAxis: YAxis?, trans: Transformer?)
    : YAxisRenderer(viewPortHandler, yAxis, trans) {

    private val arrowUpIcon: Drawable?
    private val arrowWidth: Int
    private val arrowHeight: Int

    init {
        arrowUpIcon = ContextCompat.getDrawable(context, R.drawable.ic_arrow_up)
        arrowWidth = arrowUpIcon!!.intrinsicWidth
        arrowHeight = arrowUpIcon.intrinsicHeight
    }

    override fun renderAxisLine(c: Canvas) {

        if (!mYAxis.isEnabled || !mYAxis.isDrawAxisLineEnabled) return

        mAxisLinePaint.color = mYAxis.axisLineColor
        mAxisLinePaint.strokeWidth = mYAxis.axisLineWidth

        if (mYAxis.axisDependency == YAxis.AxisDependency.LEFT) {

            //draw the left Y line axis
            c.drawLine(
                mViewPortHandler.contentLeft(),
                mViewPortHandler.contentTop(),
                mViewPortHandler.contentLeft(),
                mViewPortHandler.contentBottom(),
                mAxisLinePaint
            )

            //draw the arrowUp on top of the left Y axis
            arrowUpIcon!!.bounds =
                Rect(mViewPortHandler.contentLeft().toInt() - arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() - arrowHeight / 2,
                    mViewPortHandler.contentLeft().toInt() + arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() + arrowHeight / 2
                )
            arrowUpIcon.draw(c)
        }
        else {

            //draw the right Y line axis
            c.drawLine(
                mViewPortHandler.contentRight(),
                mViewPortHandler.contentTop(),
                mViewPortHandler.contentRight(),
                mViewPortHandler.contentBottom(),
                mAxisLinePaint
            )

            //draw the arrowUp on top of the right Y axis
            arrowUpIcon!!.bounds =
                Rect(
                    mViewPortHandler.contentRight().toInt() - arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() - arrowHeight / 2,
                    mViewPortHandler.contentRight().toInt() + arrowWidth / 2,
                    mViewPortHandler.contentTop().toInt() + arrowHeight / 2
                )
            arrowUpIcon.draw(c)
        }
    }
}

In the above samples i have used the below vector drawables where you can change based on your needs:

R.drawable.ic_arrow_right:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="@android:color/darker_gray">
    <path
        android:fillColor="@android:color/darker_gray"
        android:pathData="M8.59,16.59L13.17,12 8.59,7.41 10,6l6,6 -6,6 -1.41,-1.41z"/>
</vector>

R.drawable.ic_arrow_up:

<vector xmlns:android="http://schemas.android.com/apk/res/android"
    android:width="24dp"
    android:height="24dp"
    android:viewportWidth="24"
    android:viewportHeight="24"
    android:tint="@android:color/darker_gray">
    <path
        android:fillColor="@android:color/darker_gray"
        android:pathData="M7.41,15.41L12,10.83l4.59,4.58L18,14l-6,-6 -6,6z"/>
</vector>

Usage for X axis:

chart.setXAxisRenderer(ArrowXAxisRenderer(this, chart.getViewPortHandler(), chart.getXAxis(), chart.getTransformer(YAxis.AxisDependency.LEFT)))

Usage for Y (Left or Right) axis:

chart.setRendererLeftYAxis(ArrowYAxisRenderer(this, chart.getViewPortHandler(), chart.getAxisLeft(), chart.getTransformer(YAxis.AxisDependency.LEFT)))
chart.setRendererRightYAxis(ArrowYAxisRenderer(this, chart.getViewPortHandler(), chart.getAxisRight(), chart.getTransformer(YAxis.AxisDependency.RIGHT)))

Result:

axis_arrows

Note: This was tested with 'com.github.PhilJay:MPAndroidChart:v3.1.0'

最终幸福 2025-01-24 11:31:21

我已经检查了文档,似乎没有选项可以渲染轴之一末端的箭头或其他东西。

也许您可以为图表创建一个叠加层,但我想将箭头放在正确的位置并不是一个好主意。

I have checked the documentation and it seems that there is no option to render an arrow or something else on the end of one of the axis.

Maybe you can create an overlay for your chart, but i guess placing the arrows on the correct place is not a good idea.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文