我想为顶部和底部xAxis使用不同的值格式器,以实现类似于以下的效果:
最佳答案
由于我无法在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
我希望有这个问题的人会发现这个答案有帮助
关于android - MPAndroidChart-为顶部和底部轴绘制不同的标签,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52852596/