Reputation: 53
I have an MPAndroidChart line chart that shows dates on the xaxis & weights on the yaxis. As it is, the data points along the xaxis are all evenly spaced, but I'd like to make them relative to the time period between each weight entry. Try as I might, I can't find anything in the MPAndroidChart documentation that describes how to do this, or if it's even supported. Can anyone point me in the right direction here?
Here is the code to create the chart (with the result being even spacing):
private fun loadChart(weightList: List<FormattedWeight>) {
if (weightList.isEmpty()) { return }
val weights = ArrayList<Entry>()
val dates = ArrayList<Date>()
for (i in weightList.indices) {
val weight = weightList[i]
weights.add(Entry(i.toFloat(), weight.Weight!!.toFloat()))
dates.add(weight.WeightDate!!)
}
val dataSet = LineDataSet(weights, "Weights")
dataSet.mode = LineDataSet.Mode.LINEAR
val xaxis = binding.weightChart.xAxis
xaxis.granularity=2f
dataSet.color = Color.BLUE
dataSet.setCircleColor(Color.BLUE)
xaxis.position = XAxis.XAxisPosition.BOTTOM
xaxis.valueFormatter = object : ValueFormatter() {
private val mFormat = SimpleDateFormat.getDateInstance(SimpleDateFormat.SHORT)
override fun getFormattedValue(value: Float): String {
return try {
mFormat.format(dates[value.toInt()])
} catch (e: Exception) {
""
}
}
}
binding.weightChart.data = LineData(dataSet)
binding.weightChart.description.isEnabled = false
binding.weightChart.legend.isEnabled = false
binding.weightChart.invalidate()
binding.weightChart.moveViewToX(weights[weights.size - 1].y)
}
Even spacing
Relative spacing
Upvotes: 1
Views: 131
Reputation: 53
I figured out that the xaxis spacing is set in
Entry(float x, float y)
If you set the x parameter to evenly incremented numbers (eg: 1, 2, 3...) you will get evenly spaced data points. However if you set them to varying increments (eg: 1, 1.3, 2.2...), you'll get relative spacing. So here's the code I used to achieve this:
val spacing = calcRelativeSpacing(weightList)
for (i in weightList.indices) {
val weight = weightList[i]
weights.add(Entry(spacing[i], weight.Weight!!.toFloat()))
dates.add(weight.WeightDate!!)
}
Note the call to calcRelativeSpacing(weightList):
private fun calcRelativeSpacing(entries: List<FormattedWeight>): ArrayList<Float> {
val startDate = Instant(entries.get(0).WeightDate)
val endDate = Instant(entries.get(entries.lastIndex).WeightDate)
val days = Days.daysBetween(startDate, endDate).days
val dayInterval = (days / entries.size).toFloat()
val spacing = ArrayList<Float>()
spacing.add(1f)
for (i in 1 until entries.size) {
spacing.add(spacing[i-1] + (Days.daysBetween(Instant(entries.get(i-1).WeightDate), Instant(entries.get(i).WeightDate)).days / dayInterval))
}
return spacing
}
Upvotes: 0