遵循 4 步算法
-
- 计算数据范围
-
- 理想步长 = 范围 / (刻度数 - 1)
-
- 归一化到 10 的幂 → 取 1/2/2.5/5 系数 → 得到规整步长
-
- 轴起点向下取整、终点向上取整到步长的整数倍
object NiceNumberUtil {
fun calculateNiceRange(
yAxis: YAxis,
minValue: Double,
maxValue: Double,
tickCount: Int = 5
) {
val range = maxValue - minValue
val roughStep = range / (tickCount - 1)
val niceStep = niceNumberNew(roughStep, round = true)
val niceMin = floor(minValue / niceStep) * niceStep
val niceMax = ceil(maxValue / niceStep) * niceStep
val finalMax = if (niceMax == niceMin) {
niceMin + niceStep
} else {
niceMax
}
yAxis.axisMaximum = finalMax.toFloat()
yAxis.axisMinimum = niceMin.toFloat()
yAxis.labelCount = tickCount
yAxis.setLabelCount(tickCount, true)
}
private fun niceNumberNew(value: Double, round: Boolean): Double {
val exponent = floor(log10(value))
val fraction = value / 10.0.pow(exponent)
val niceFraction: Double
if (round) {
niceFraction = when {
fraction <= 1.0 -> 1.0
fraction <= 2.0 -> 2.0
fraction <= 2.5 -> 2.5
fraction <= 5.0 -> 5.0
else -> 10.0
}
} else {
niceFraction = when {
fraction < 1.0 -> 1.0
fraction < 2.0 -> 2.0
fraction < 2.5 -> 2.5
fraction < 5.0 -> 5.0
else -> 10.0
}
}
return niceFraction * 10.0.pow(exponent)
}
private fun niceNumber(value: Double, round: Boolean): Double {
val exponent = floor(log10(value))
val fraction = value / 10.0.pow(exponent)
val niceFraction: Double
if (round) {
niceFraction = when {
fraction < 1.5 -> 1.0
fraction < 3.0 -> 2.0
fraction < 7.0 -> 5.0
else -> 10.0
}
} else {
niceFraction = when {
fraction <= 1.0 -> 1.0
fraction <= 2.0 -> 2.0
fraction <= 5.0 -> 5.0
else -> 10.0
}
}
return niceFraction * 10.0.pow(exponent)
}
data class NiceAxisResult(
val min: Double,
val max: Double,
val tickSpacing: Double
) {
fun getTickValues(): List<Double> {
val ticks = mutableListOf<Double>()
var current = min
while (current <= max + 1e-10) {
ticks.add(current)
current += tickSpacing
}
return ticks
}
}
}