Так как мне не удалось найти решение этой проблемы в StackOverflow, я решил опубликовать свое собственное.
Для этого нам необходимо предоставить пользовательскую реализацию XAxisRenderer
:
class DoubleXLabelAxisRenderer(
viewPortHandler: ViewPortHandler,
xAxis: XAxis,
transformer: Transformer,
private val topValueFormatter: IAxisValueFormatter) : XAxisRenderer(viewPortHandler, xAxis, transformer) {
override fun renderAxisLabels(c: Canvas) {
if (!mXAxis.isEnabled || !mXAxis.isDrawLabelsEnabled)
return
val yoffset = mXAxis.yOffset
mAxisLabelPaint.typeface = mXAxis.typeface
mAxisLabelPaint.textSize = mXAxis.textSize
mAxisLabelPaint.color = mXAxis.textColor
val pointF = MPPointF.getInstance(0f, 0f)
if (mXAxis.position == XAxis.XAxisPosition.TOP) {
pointF.x = 0.5f
pointF.y = 1.0f
drawLabels(c, mViewPortHandler.contentTop() - yoffset, pointF)
} else if (mXAxis.position == XAxis.XAxisPosition.TOP_INSIDE) {
pointF.x = 0.5f
pointF.y = 1.0f
drawLabels(c, mViewPortHandler.contentTop() + yoffset + mXAxis.mLabelRotatedHeight.toFloat(), pointF)
} else if (mXAxis.position == XAxis.XAxisPosition.BOTTOM) {
pointF.x = 0.5f
pointF.y = 0.0f
drawLabels(c, mViewPortHandler.contentBottom() + yoffset, pointF)
} else if (mXAxis.position == XAxis.XAxisPosition.BOTTOM_INSIDE) {
pointF.x = 0.5f
pointF.y = 0.0f
drawLabels(c, mViewPortHandler.contentBottom() - yoffset - mXAxis.mLabelRotatedHeight.toFloat(), pointF)
} else { // BOTH SIDED
pointF.x = 0.5f
pointF.y = 1.0f
drawLabelsTop(c, mViewPortHandler.contentTop() - yoffset, pointF)
pointF.x = 0.5f
pointF.y = 0.0f
drawLabels(c, mViewPortHandler.contentBottom() + yoffset, pointF)
}
MPPointF.recycleInstance(pointF)
}
private fun drawLabelsTop(c: Canvas, pos: Float, anchor: MPPointF) {
val labelRotationAngleDegrees = mXAxis.labelRotationAngle
val centeringEnabled = mXAxis.isCenterAxisLabelsEnabled
val positions = FloatArray(mXAxis.mEntryCount * 2)
for(i in 0 until positions.size step 2) {
if (centeringEnabled) {
positions[i] = mXAxis.mCenteredEntries[i / 2]
} else {
positions[i] = mXAxis.mEntries[i / 2]
}
}
mTrans.pointValuesToPixel(positions)
for(i in 0 until positions.size step 2) {
var x = positions[i]
if (mViewPortHandler.isInBoundsX(x)) {
val label = topValueFormatter.getFormattedValue(mXAxis.mEntries[i / 2], mXAxis)
if (mXAxis.isAvoidFirstLastClippingEnabled) {
if (i == mXAxis.mEntryCount - 1 && mXAxis.mEntryCount > 1) {
val width = Utils.calcTextWidth(mAxisLabelPaint, label).toFloat()
if (width > mViewPortHandler.offsetRight() * 2 && x + width > mViewPortHandler.chartWidth)
x -= width / 2
} else if (i == 0) {
val width = Utils.calcTextWidth(mAxisLabelPaint, label).toFloat()
x += width / 2
}
}
drawLabel(c, label, x, pos, anchor, labelRotationAngleDegrees)
}
}
}
}
А затем установите его на нашем графике:
chart.setXAxisRenderer(
DoubleXLabelAxisRenderer(
chart.viewPortHandler,
chart.xAxis,
chart.getTransformer(YAxis.AxisDependency.LEFT),
IAxisValueFormatter { value, axis -> "someCustomValueForTopLabel" }))
И, конечно, положение xAxis должно быть установлено в обе стороны:
chart.xAxis.position = XAxis.XAxisPosition.BOTH_SIDED
Iнадеюсь, кто-то с этой проблемой найдет этот ответ полезным