android - MpAndroidChart:将箭头添加到轴的末端

标签 android mpandroidchart

我想在轴的末端放置一个箭头,但我不知道如何在 MPAndroidCharts 库中实现这一点。最后应该是这样的。 Chart

我目前的风格:

  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)

最佳答案

要在 X 轴和 Y 轴的末端添加箭头,您必须制作自定义 XAxisRendererYAxisRenderer。您所要做的就是为每个渲染器创建一个子类并覆盖公共(public)方法 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)))

结果:

axis_arrows

注意:这是使用“com.github.PhilJay:MPAndroidChart:v3.1.0”测试的

关于android - MpAndroidChart:将箭头添加到轴的末端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71647308/

相关文章:

java - 创建显示空指针异常的新 Intent

c# - 是否可以编译一个C#程序在Android手机上运行?

android - 使用 NDK 编译链接(未复制)文件

android - 如何在 MPAndroidChart 中使用 setLabelCount(...)?

android - 如何在 Kotlin 中使用 MPAndroidChart 为条形图添加带有一些详细信息的标记?

android - MPAndroidChart 添加和显示条形图标签

android - Flutter:当小部件树被锁定时调用 setState() 或 markNeedsBuild() ... 在方向更改期间

android - 游标在 Android 开发中有什么用?

android - 如何使我的 Horizo​​ntalBarChart 可滚动?

Android MP 饼图如何从饼图中删除文本和值