gpt4 book ai didi

android - 如何使用 mpchart 设置 xAxis 显示独立于条目的特定值

转载 作者:行者123 更新时间:2023-12-05 04:49:13 24 4
gpt4 key购买 nike

例如,我有如下数据集:

val dataSetX = {101, 205, 210, 445, 505}
val dataSetY = {50, 100, 150, 200, 250}

图表 x 轴上的标签将为 101、205、295、445、505。

但我希望它们是 100,200,300,400,500,而不更改数据。

我该怎么办?

最佳答案

为了能够独立于数据输入列表呈现自定义标签,您需要实现自定义 XAxisRenderer 并覆盖函数 fun drawLabels(c: Canvas?, pos: Float, anchor : MPPointF?) 当标签准备好在 Canvas 上绘制时调用。默认实现使用 mXAxis.mEntryCountmXAxis.mEntries 来呈现由库内部计算的 xAxis 中的标签。您可以做的是在不调用 super.drawLabels(c, pos, anchor) 方法的情况下通过覆盖它来修改父类(super class)实现,并进行处理自定义标签所需的调整。下面我将介绍如何实现这一目标。

1.) 首先声明从 XAxisRenderer 扩展而来的 CustomXAxisRenderer,如下例所示:

class CustomXAxisRenderer(viewPortHandler: ViewPortHandler?, xAxis: XAxis?, trans: Transformer?, renderXArray : Array<Float>, formatter: ValueFormatter)
: XAxisRenderer(viewPortHandler, xAxis, trans) {

private val xArray : Array<Float>
private val xValueFormatter: ValueFormatter

init {
xArray = renderXArray
xValueFormatter = formatter
}

override fun drawLabels(c: Canvas?, pos: Float, anchor: MPPointF?) {
//don't call the super class to draw the default x points
//super.drawLabels(c, pos, anchor)

val labelRotationAngleDegrees = mXAxis.labelRotationAngle
val centeringEnabled = false//mXAxis.isCenterAxisLabelsEnabled

val positions = FloatArray(xArray.size * 2)

for(i in positions.indices step 2){

// only fill x values
if (centeringEnabled) {
positions[i.toInt()] = mXAxis.mCenteredEntries[(i / 2).toInt()]
} else {
positions[i.toInt()] = xArray[(i / 2).toInt()]
}
}

mTrans.pointValuesToPixel(positions)

for(i in positions.indices step 2){

var x = positions[i]

if (mViewPortHandler.isInBoundsX(x)) {
val label = xValueFormatter.getAxisLabel(xArray[i / 2], mXAxis)
if (mXAxis.isAvoidFirstLastClippingEnabled) {

// avoid clipping of the last
if (i / 2 == xArray.size - 1 && xArray.size > 1) {
val width = Utils.calcTextWidth(mAxisLabelPaint, label).toFloat()
if (width > mViewPortHandler.offsetRight() * 2 && x + width > mViewPortHandler.chartWidth)
x -= width / 2

// avoid clipping of the first
} else if (i == 0) {
val width = Utils.calcTextWidth(mAxisLabelPaint, label).toFloat()
x += width / 2
}
}
drawLabel(c, label, x, pos, anchor, labelRotationAngleDegrees)
}
}
}
}

2.)然后你可以像下面这样使用它:

//prepare an Array of the x points to render independent of the x points in the Data Entry List
//below values must be between AxisMinimum and AxisMaximum
val renderXArray = arrayOf<Float>(0f, 150f, 250f, 350f, 400f, 433f, 505f)
//and set a custom XAxisRenderer
chart.setXAxisRenderer(CustomXAxisRenderer(chart.getViewPortHandler(), chart.getXAxis(), chart.getTransformer(YAxis.AxisDependency.LEFT), renderXArray, object : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
return value.toInt().toString()
}
}))

如果您需要根据值返回特定的标签字符串,您可以使用 ValueFormatter,如下所示:

chart.setXAxisRenderer(CustomXAxisRenderer(chart.getViewPortHandler(), chart.getXAxis(), chart.getTransformer(YAxis.AxisDependency.LEFT), renderXArray, object : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
return when (value) {
0f -> "A"
150f -> "B"
250f -> "C"
350f -> "D"
400f -> "E"
433f -> "F"
505f -> "G"
else -> ""
}
}
}))

完整示例:

chart = findViewById<LineChart>(R.id.chart)

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

//set xAxis Min/Max and Granularity
xAxis.setAxisMinimum(0f)
xAxis.setAxisMaximum(505f)
xAxis.setGranularity(1f)
xAxis.setGranularityEnabled(true)

//set axisLeft properties
val axisLeft = chart.axisLeft
axisLeft.setDrawLabels(true)
axisLeft.setDrawGridLines(true)
axisLeft.setDrawZeroLine(true)
axisLeft.axisLineWidth = 1.5f
axisLeft.setDrawTopYLabelEntry(true)

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

//prepare the Entry points
val values: ArrayList<Entry> = ArrayList()
values.add(Entry(101f, 50f))
values.add(Entry(205f, 100f))
values.add(Entry(210f, 150f))
values.add(Entry(445f, 200f))
values.add(Entry(505f, 250f))

//set the LineDataSet
val set1 = LineDataSet(values, "")
set1.setDrawCircles(true);
set1.setDrawValues(true);

//prepare LineData and set them to LineChart
val dataSets: ArrayList<ILineDataSet> = ArrayList()
dataSets.add(set1)
val data = LineData(dataSets)
chart.setData(data)
chart.getDescription().setEnabled(false);
chart.legend.isEnabled = false

//prepare an Array of the x points to render independent of the x points in the Data Entry List
//below values must be between AxisMinimum and AxisMaximum
val renderXArray = arrayOf<Float>(0f, 150f, 250f, 350f, 400f, 433f, 505f)
//and set a custom XAxisRenderer
chart.setXAxisRenderer(CustomXAxisRenderer(chart.getViewPortHandler(), chart.getXAxis(), chart.getTransformer(YAxis.AxisDependency.LEFT), renderXArray, object : ValueFormatter() {
override fun getFormattedValue(value: Float): String {
return value.toInt().toString()
}
}))

值结果:

value_result

标签结果:

label_result

注意:这是使用版本 'com.github.PhilJay:MPAndroidChart:v3.1.0'

测试的

关于android - 如何使用 mpchart 设置 xAxis 显示独立于条目的特定值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67667952/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com