mirror of
https://github.com/dzeiocom/OpenHealth.git
synced 2025-06-07 07:19:54 +00:00
misc: Continue working on Chart
This commit is contained in:
parent
39c7c507c5
commit
196fcf5da0
@ -41,6 +41,8 @@ class StepsHomeFragment :
|
|||||||
|
|
||||||
viewModel.items.observe(viewLifecycleOwner) { list ->
|
viewModel.items.observe(viewLifecycleOwner) { list ->
|
||||||
adapter.set(list)
|
adapter.set(list)
|
||||||
|
chart.numberOfEntries = list.size
|
||||||
|
chart.numberOfLabels = 2
|
||||||
|
|
||||||
val strings = ArrayList<String>()
|
val strings = ArrayList<String>()
|
||||||
val values = ArrayList<Int>()
|
val values = ArrayList<Int>()
|
||||||
@ -50,10 +52,14 @@ class StepsHomeFragment :
|
|||||||
values.add(it.value)
|
values.add(it.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
chart.yAxis.max = 10
|
||||||
|
|
||||||
|
|
||||||
chart.setBottomTextList(strings)
|
chart.setBottomTextList(strings)
|
||||||
chart.setDataList(
|
chart.setDataList(
|
||||||
values
|
values
|
||||||
)
|
)
|
||||||
|
chart.refresh()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
6
charts/src/main/java/com/dzeio/charts/Axis.kt
Normal file
6
charts/src/main/java/com/dzeio/charts/Axis.kt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package com.dzeio.charts
|
||||||
|
|
||||||
|
class Axis<T> {
|
||||||
|
var max: T? = null
|
||||||
|
var min: T? = null
|
||||||
|
}
|
6
charts/src/main/java/com/dzeio/charts/Entry.kt
Normal file
6
charts/src/main/java/com/dzeio/charts/Entry.kt
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
package com.dzeio.charts
|
||||||
|
|
||||||
|
data class Entry(
|
||||||
|
val x: Float,
|
||||||
|
val y: Double
|
||||||
|
)
|
@ -8,7 +8,11 @@ import android.graphics.Rect
|
|||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import com.dzeio.charts.Axis
|
||||||
|
import com.dzeio.charts.Entry
|
||||||
import kotlin.math.abs
|
import kotlin.math.abs
|
||||||
|
import kotlin.math.max
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
class BarChartView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null) :
|
class BarChartView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null) :
|
||||||
View(context, attrs) {
|
View(context, attrs) {
|
||||||
@ -20,23 +24,21 @@ class BarChartView @JvmOverloads constructor(context: Context?, attrs: Attribute
|
|||||||
/**
|
/**
|
||||||
* Nunber of entries displayed at the same time
|
* Nunber of entries displayed at the same time
|
||||||
*/
|
*/
|
||||||
val numberOfEntries = 5
|
var numberOfEntries = 5
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of labels displayed at the same time
|
* Number of labels displayed at the same time
|
||||||
*/
|
*/
|
||||||
val numberOfLabels = 3
|
var numberOfLabels = 3
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Spacing between entries
|
* Spacing between entries
|
||||||
*/
|
*/
|
||||||
val spacing = 22
|
var spacing = 22
|
||||||
|
|
||||||
/**
|
val xAxis: Axis<Int> = Axis()
|
||||||
* top margin from the canvas
|
|
||||||
*/
|
val yAxis: Axis<Int> = Axis()
|
||||||
@Deprecated("Not needed anymore, Use the parent Padding/Margin")
|
|
||||||
private val topMargin: Int = 5
|
|
||||||
|
|
||||||
private val textTopMargin = 5
|
private val textTopMargin = 5
|
||||||
|
|
||||||
@ -84,13 +86,25 @@ class BarChartView @JvmOverloads constructor(context: Context?, attrs: Attribute
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun setList(list: ArrayList<Entry>) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun refresh(animate: Boolean = true) {
|
||||||
|
if (animate) {
|
||||||
|
removeCallbacks(animator)
|
||||||
|
post(animator)
|
||||||
|
} else {
|
||||||
|
postInvalidate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* dataList will be reset when called is method.
|
* dataList will be reset when called is method.
|
||||||
*
|
*
|
||||||
* @param bottomStringList The String ArrayList in the bottom.
|
* @param bottomStringList The String ArrayList in the bottom.
|
||||||
*/
|
*/
|
||||||
fun setBottomTextList(bottomStringList: ArrayList<String>?) {
|
fun setBottomTextList(bottomStringList: ArrayList<String>?) {
|
||||||
barWidth = measuredWidth / numberOfEntries - spacing
|
|
||||||
bottomTextList = bottomStringList
|
bottomTextList = bottomStringList
|
||||||
val r = Rect()
|
val r = Rect()
|
||||||
bottomTextDescent = 0
|
bottomTextDescent = 0
|
||||||
@ -99,7 +113,7 @@ class BarChartView @JvmOverloads constructor(context: Context?, attrs: Attribute
|
|||||||
if (bottomTextHeight < r.height()) {
|
if (bottomTextHeight < r.height()) {
|
||||||
bottomTextHeight = r.height()
|
bottomTextHeight = r.height()
|
||||||
}
|
}
|
||||||
Log.d(TAG, measuredWidth.toString())
|
// Log.d(TAG, measuredWidth.toString())
|
||||||
// if (autoSetWidth && barWidth < r.width()) {
|
// if (autoSetWidth && barWidth < r.width()) {
|
||||||
// barWidth = r.width()
|
// barWidth = r.width()
|
||||||
// }
|
// }
|
||||||
@ -107,7 +121,6 @@ class BarChartView @JvmOverloads constructor(context: Context?, attrs: Attribute
|
|||||||
bottomTextDescent = abs(r.bottom)
|
bottomTextDescent = abs(r.bottom)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
postInvalidate()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,7 +129,7 @@ class BarChartView @JvmOverloads constructor(context: Context?, attrs: Attribute
|
|||||||
fun setDataList(list: ArrayList<Int>) {
|
fun setDataList(list: ArrayList<Int>) {
|
||||||
barWidth = measuredWidth / numberOfEntries - spacing
|
barWidth = measuredWidth / numberOfEntries - spacing
|
||||||
// Calculate max
|
// Calculate max
|
||||||
val max = list.reduce { acc, i -> if (acc > i) return@reduce acc else return@reduce i }
|
val max = yAxis.max ?: list.reduce { acc, i -> return@reduce if (acc > i) acc else i }
|
||||||
|
|
||||||
targetPercentList = ArrayList()
|
targetPercentList = ArrayList()
|
||||||
for (integer in list) {
|
for (integer in list) {
|
||||||
@ -135,35 +148,63 @@ class BarChartView @JvmOverloads constructor(context: Context?, attrs: Attribute
|
|||||||
percentList.removeAt(percentList.size - 1)
|
percentList.removeAt(percentList.size - 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
removeCallbacks(animator)
|
|
||||||
post(animator)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDraw(canvas: Canvas) {
|
override fun onDraw(canvas: Canvas) {
|
||||||
if (percentList.isNotEmpty()) {
|
if (percentList.isNotEmpty()) {
|
||||||
for (i in 1 until percentList.size) {
|
for (i in 1 until percentList.size) {
|
||||||
val left = spacing * i + barWidth * (i - 1)
|
val left = spacing * i + barWidth * (i - 1)
|
||||||
Log.d(TAG, "$spacing, $i, $barWidth = $left")
|
// Log.d(TAG, "$spacing, $i, $barWidth = $left")
|
||||||
val right = (spacing + barWidth) * i
|
val right = (spacing + barWidth) * i
|
||||||
val bottom = height - bottomTextHeight - textTopMargin
|
val bottom = height - bottomTextHeight - textTopMargin
|
||||||
val top = topMargin + ((bottom - topMargin) * percentList[i - 1])
|
val top = bottom * percentList[i - 1]
|
||||||
|
|
||||||
rect.set(left, top.toInt(), right, bottom)
|
rect.set(left, top.toInt(), right, bottom)
|
||||||
|
|
||||||
canvas.drawRect(rect, fgPaint)
|
canvas.drawRect(rect, fgPaint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (bottomTextList != null && !bottomTextList!!.isEmpty()) {
|
if (bottomTextList != null && bottomTextList!!.isNotEmpty() && numberOfLabels > 0) {
|
||||||
|
val rect = Rect()
|
||||||
|
val size = bottomTextList!!.size
|
||||||
var i = 1
|
var i = 1
|
||||||
|
var items = size / max(2, (numberOfLabels - 2))
|
||||||
|
|
||||||
|
// handle cases where size is even and numberOfLabels is 3
|
||||||
|
if (size % 2 != 0) {
|
||||||
|
items += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(TAG, "$size / max($numberOfLabels - 2, 2) = $items")
|
||||||
for (s in bottomTextList!!) {
|
for (s in bottomTextList!!) {
|
||||||
|
|
||||||
|
if ((numberOfLabels <= 2 || i % items != 0) && i != 1 && i != size) {
|
||||||
|
i++
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.i(TAG, "Drawing $i")
|
||||||
|
|
||||||
|
textPaint.getTextBounds(s, 0, s.length, rect)
|
||||||
|
|
||||||
canvas.drawText(
|
canvas.drawText(
|
||||||
s,
|
s,
|
||||||
(spacing * i + barWidth * (i - 1) + barWidth / 2).toFloat(),
|
// handle last entry overflowing
|
||||||
|
min(
|
||||||
|
// handle first entry overflowing
|
||||||
|
max(
|
||||||
|
(spacing * i + barWidth * (i - 1) + barWidth / 2).toFloat(),
|
||||||
|
rect.width() / 2f
|
||||||
|
),
|
||||||
|
measuredWidth - rect.width() / 2f
|
||||||
|
),
|
||||||
(height - bottomTextDescent).toFloat(),
|
(height - bottomTextDescent).toFloat(),
|
||||||
textPaint
|
textPaint
|
||||||
)
|
)
|
||||||
i++
|
i++
|
||||||
|
if (numberOfLabels == 1) {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user