mirror of
https://github.com/dzeiocom/OpenHealth.git
synced 2025-04-23 19:32:11 +00:00
fix: label not correctly positionned
This commit is contained in:
parent
57eef94f31
commit
07d150968e
@ -47,9 +47,42 @@ class StepsHomeFragment :
|
|||||||
|
|
||||||
val chart = binding.chart
|
val chart = binding.chart
|
||||||
|
|
||||||
val serie = BarSerie(chart)
|
// setup serie
|
||||||
|
val serie = BarSerie(chart).apply {
|
||||||
|
barPaint.color = MaterialColors.getColor(
|
||||||
|
requireView(),
|
||||||
|
com.google.android.material.R.attr.colorPrimary
|
||||||
|
)
|
||||||
|
textPaint.color = MaterialColors.getColor(
|
||||||
|
requireView(),
|
||||||
|
com.google.android.material.R.attr.colorOnPrimary
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
chart.series = arrayListOf(serie)
|
chart.apply {
|
||||||
|
series = arrayListOf(serie)
|
||||||
|
debug = true
|
||||||
|
|
||||||
|
yAxis.apply {
|
||||||
|
setYMin(0f)
|
||||||
|
textLabel.color = MaterialColors.getColor(
|
||||||
|
requireView(),
|
||||||
|
com.google.android.material.R.attr.colorOnPrimaryContainer
|
||||||
|
)
|
||||||
|
linePaint.color = MaterialColors.getColor(
|
||||||
|
requireView(),
|
||||||
|
com.google.android.material.R.attr.colorOnPrimaryContainer
|
||||||
|
)
|
||||||
|
//
|
||||||
|
onValueFormat = { value -> "${value.toInt()}" }
|
||||||
|
}
|
||||||
|
|
||||||
|
xAxis.apply {
|
||||||
|
increment = 3600000.0
|
||||||
|
displayCount = 168
|
||||||
|
// displayCount = 24
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
viewModel.items.observe(viewLifecycleOwner) { list ->
|
viewModel.items.observe(viewLifecycleOwner) { list ->
|
||||||
adapter.set(list)
|
adapter.set(list)
|
||||||
@ -68,34 +101,12 @@ class StepsHomeFragment :
|
|||||||
// )
|
// )
|
||||||
|
|
||||||
// chart.xAxis.labels.size = 32f
|
// chart.xAxis.labels.size = 32f
|
||||||
chart.yAxis.apply {
|
|
||||||
setYMin(0f)
|
|
||||||
textLabel.color = MaterialColors.getColor(
|
|
||||||
requireView(),
|
|
||||||
com.google.android.material.R.attr.colorOnBackground
|
|
||||||
)
|
|
||||||
// linePaint.color = MaterialColors.getColor(
|
|
||||||
// requireView(),
|
|
||||||
// com.google.android.material.R.attr.colorOutline
|
|
||||||
// )
|
|
||||||
// onValueFormat = onValueFormat@{ value, short ->
|
|
||||||
// if (short) {
|
|
||||||
// return@onValueFormat value.toInt().toString()
|
|
||||||
// } else {
|
|
||||||
// return@onValueFormat "${value.toInt()} steps"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
serie.entries = list.reversed().map {
|
serie.entries = list.reversed().map {
|
||||||
return@map Entry(it.timestamp.toDouble(), it.value.toFloat())
|
return@map Entry(it.timestamp.toDouble(), it.value.toFloat())
|
||||||
} as ArrayList<Entry>
|
} as ArrayList<Entry>
|
||||||
|
|
||||||
chart.xAxis.apply {
|
chart.xAxis.x = serie.entries.first().x
|
||||||
increment = (1000 * 60 * 60).toDouble()
|
|
||||||
displayCount = 24 * 7
|
|
||||||
x = serie.entries.first().x
|
|
||||||
}
|
|
||||||
|
|
||||||
// chart.xAxis.onValueFormat = onValueFormat@{
|
// chart.xAxis.onValueFormat = onValueFormat@{
|
||||||
// val formatter = DateFormat.getDateTimeInstance(
|
// val formatter = DateFormat.getDateTimeInstance(
|
||||||
|
@ -2,11 +2,7 @@ package com.dzeio.openhealth.ui.weight
|
|||||||
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.LayoutInflater
|
import android.view.*
|
||||||
import android.view.Menu
|
|
||||||
import android.view.MenuItem
|
|
||||||
import android.view.View
|
|
||||||
import android.view.ViewGroup
|
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
import androidx.navigation.fragment.findNavController
|
import androidx.navigation.fragment.findNavController
|
||||||
import androidx.preference.PreferenceManager
|
import androidx.preference.PreferenceManager
|
||||||
@ -37,6 +33,7 @@ class ListWeightFragment :
|
|||||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||||
super.onViewCreated(view, savedInstanceState)
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
|
||||||
|
// FIXME: deprecated
|
||||||
setHasOptionsMenu(true)
|
setHasOptionsMenu(true)
|
||||||
|
|
||||||
if (viewModel.goalWeight != null) {
|
if (viewModel.goalWeight != null) {
|
||||||
|
@ -50,9 +50,12 @@ class ChartView @JvmOverloads constructor(context: Context?, attrs: AttributeSet
|
|||||||
}, debugStrokePaint)
|
}, debugStrokePaint)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// right distance from the yAxis
|
||||||
|
val rightDistance = yAxis.onDraw(canvas)
|
||||||
|
|
||||||
// chart draw rectangle
|
// chart draw rectangle
|
||||||
rect.apply {
|
rect.apply {
|
||||||
set(0f, 0f, width.toFloat(), height.toFloat())
|
set(0f, 8f, width.toFloat() - 16f - rightDistance, height.toFloat() - 16f)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (serie in series) {
|
for (serie in series) {
|
||||||
|
@ -29,7 +29,7 @@ interface ChartViewInterface {
|
|||||||
var series: ArrayList<SerieInterface>
|
var series: ArrayList<SerieInterface>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* refresh EVERYTHING
|
* refresh the chart
|
||||||
*/
|
*/
|
||||||
fun refresh()
|
fun refresh()
|
||||||
}
|
}
|
@ -1,23 +0,0 @@
|
|||||||
package com.dzeio.charts
|
|
||||||
|
|
||||||
import android.graphics.Color
|
|
||||||
import android.graphics.Paint
|
|
||||||
import androidx.annotation.ColorInt
|
|
||||||
|
|
||||||
class XAxisLabels {
|
|
||||||
|
|
||||||
var size = 25f
|
|
||||||
|
|
||||||
@ColorInt
|
|
||||||
var color: Int = Color.parseColor("#9B9A9B")
|
|
||||||
|
|
||||||
fun build(): Paint {
|
|
||||||
return Paint().also {
|
|
||||||
it.isAntiAlias = true
|
|
||||||
it.color = color
|
|
||||||
it.textSize = size
|
|
||||||
it.isFakeBoldText = true
|
|
||||||
it.textAlign = Paint.Align.CENTER
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -3,27 +3,37 @@ package com.dzeio.charts.axis
|
|||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.graphics.RectF
|
import android.graphics.Rect
|
||||||
import com.dzeio.charts.ChartViewInterface
|
import com.dzeio.charts.ChartViewInterface
|
||||||
|
import com.dzeio.charts.utils.drawDottedLine
|
||||||
|
|
||||||
class YAxis(
|
class YAxis(
|
||||||
private val view: ChartViewInterface
|
private val view: ChartViewInterface
|
||||||
) : YAxisInterface {
|
) : YAxisInterface {
|
||||||
|
|
||||||
override var enabled = false
|
override var enabled = true
|
||||||
|
|
||||||
override val textLabel = Paint().apply {
|
override val textLabel = Paint().apply {
|
||||||
isAntiAlias = true
|
isAntiAlias = true
|
||||||
color = Color.parseColor("#FC496D")
|
color = Color.parseColor("#FC496D")
|
||||||
textSize = 30f
|
textSize = 30f
|
||||||
textAlign = Paint.Align.RIGHT
|
textAlign = Paint.Align.LEFT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override val linePaint = Paint().apply {
|
||||||
|
isAntiAlias = true
|
||||||
|
color = Color.BLUE
|
||||||
|
}
|
||||||
|
|
||||||
|
var onValueFormat: (value: Float) -> String = { it -> it.toString()}
|
||||||
|
|
||||||
override var labelCount: Int = 3
|
override var labelCount: Int = 3
|
||||||
|
|
||||||
private var min: Float? = null
|
private var min: Float? = null
|
||||||
private var max: Float? = null
|
private var max: Float? = null
|
||||||
|
|
||||||
|
private val rect = Rect()
|
||||||
|
|
||||||
override fun setYMin(yMin: Float?): YAxisInterface {
|
override fun setYMin(yMin: Float?): YAxisInterface {
|
||||||
min = yMin
|
min = yMin
|
||||||
return this
|
return this
|
||||||
@ -66,22 +76,34 @@ class YAxis(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDraw(canvas: Canvas, drawLocation: RectF) {
|
override fun onDraw(canvas: Canvas): Float {
|
||||||
|
if (!enabled) {
|
||||||
|
return 0f
|
||||||
|
}
|
||||||
val min = getYMin()
|
val min = getYMin()
|
||||||
val max = getYMax() - min
|
val max = getYMax() - min
|
||||||
val top = drawLocation.top
|
val top = 0
|
||||||
val bottom = drawLocation.bottom
|
val bottom = canvas.height.toFloat()
|
||||||
|
var maxWidth = 0f
|
||||||
|
|
||||||
val increment = (bottom - top) / labelCount
|
val increment = (bottom - top) / labelCount
|
||||||
val valueIncrement = (max - min) / labelCount
|
val valueIncrement = (max - min) / labelCount
|
||||||
for (index in 0 until labelCount) {
|
for (index in 0 until labelCount) {
|
||||||
|
val text = onValueFormat((valueIncrement * (index + 1))).toString()
|
||||||
|
textLabel.getTextBounds(text, 0, text.length, rect)
|
||||||
|
maxWidth = maxWidth.coerceAtLeast(rect.width().toFloat())
|
||||||
|
|
||||||
|
val posY = bottom - (index + 1) * increment
|
||||||
|
|
||||||
canvas.drawText(
|
canvas.drawText(
|
||||||
(valueIncrement * (labelCount + 1)).toString(),
|
text,
|
||||||
bottom - (index + 1) * increment,
|
canvas.width - rect.width().toFloat(),
|
||||||
drawLocation.right,
|
posY + rect.height() + 8f,
|
||||||
textLabel
|
textLabel
|
||||||
)
|
)
|
||||||
|
canvas.drawDottedLine(0f, posY, canvas.width.toFloat(), posY, 40f, linePaint)
|
||||||
|
|
||||||
}
|
}
|
||||||
TODO("IDK if it works tbh")
|
return maxWidth
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,6 @@ package com.dzeio.charts.axis
|
|||||||
|
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
import android.graphics.RectF
|
|
||||||
|
|
||||||
sealed interface YAxisInterface {
|
sealed interface YAxisInterface {
|
||||||
|
|
||||||
@ -52,7 +51,14 @@ sealed interface YAxisInterface {
|
|||||||
val textLabel: Paint
|
val textLabel: Paint
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* function that draw our legend
|
* paint for the dotted line
|
||||||
*/
|
*/
|
||||||
fun onDraw(canvas: Canvas, drawLocation: RectF)
|
val linePaint: Paint
|
||||||
|
|
||||||
|
/**
|
||||||
|
* function that draw our legend
|
||||||
|
*
|
||||||
|
* @return the width of the sidebar
|
||||||
|
*/
|
||||||
|
fun onDraw(canvas: Canvas): Float
|
||||||
}
|
}
|
@ -1,10 +1,9 @@
|
|||||||
package com.dzeio.charts.series
|
package com.dzeio.charts.series
|
||||||
|
|
||||||
import android.graphics.Canvas
|
import android.graphics.*
|
||||||
import android.graphics.Color
|
import android.util.Log
|
||||||
import android.graphics.Paint
|
|
||||||
import android.graphics.RectF
|
|
||||||
import com.dzeio.charts.ChartView
|
import com.dzeio.charts.ChartView
|
||||||
|
import com.dzeio.charts.utils.drawRoundRect
|
||||||
|
|
||||||
class BarSerie(
|
class BarSerie(
|
||||||
private val view: ChartView
|
private val view: ChartView
|
||||||
@ -19,6 +18,15 @@ class BarSerie(
|
|||||||
color = Color.parseColor("#123456")
|
color = Color.parseColor("#123456")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val textPaint = Paint().apply {
|
||||||
|
isAntiAlias = true
|
||||||
|
color = Color.parseColor("#FC496D")
|
||||||
|
textSize = 30f
|
||||||
|
textAlign = Paint.Align.CENTER
|
||||||
|
}
|
||||||
|
|
||||||
|
private val rect = Rect()
|
||||||
|
|
||||||
override fun onDraw(canvas: Canvas, drawableSpace: RectF) {
|
override fun onDraw(canvas: Canvas, drawableSpace: RectF) {
|
||||||
val spacing = drawableSpace.width() / view.xAxis.displayCount / 10
|
val spacing = drawableSpace.width() / view.xAxis.displayCount / 10
|
||||||
val barWidth = drawableSpace.width() / view.xAxis.displayCount - spacing
|
val barWidth = drawableSpace.width() / view.xAxis.displayCount - spacing
|
||||||
@ -30,38 +38,61 @@ class BarSerie(
|
|||||||
|
|
||||||
for (entry in displayedEntries) {
|
for (entry in displayedEntries) {
|
||||||
// calculated height in percent from 0 to 100
|
// calculated height in percent from 0 to 100
|
||||||
val height = (1 - entry.y / max) * drawableSpace.height()
|
val top = (1 - entry.y / max) * drawableSpace.height()
|
||||||
// -1.945763981752553E-21
|
val posX = (view.xAxis.getPositionOnRect(entry, drawableSpace) - view.xAxis.getXOffset(drawableSpace)).toFloat()
|
||||||
// 2.103653925902835E-21
|
|
||||||
val posX = view.xAxis.getPositionOnRect(entry, drawableSpace) - view.xAxis.getXOffset(drawableSpace) - canvas.width
|
|
||||||
// Log.d(TAG, "gpor = ${view.xAxis.getPositionOnRect(entry, space)}, gxo = ${view.xAxis.getXOffset(space)}")
|
// Log.d(TAG, "gpor = ${view.xAxis.getPositionOnRect(entry, space)}, gxo = ${view.xAxis.getXOffset(space)}")
|
||||||
// Log.d(TAG, "max = $max, y = ${entry.y}, height = $height")
|
// Log.d(TAG, "max = $max, y = ${entry.y}, height = $height")
|
||||||
// Log.d(TAG, "posX: ${posX / 60 / 60 / 1000}, offsetX = ${view.xAxis.x / (1000 * 60 * 60)}, x = ${entry.x / (1000 * 60 * 60)}, pouet: ${(view.xAxis.x + view.xAxis.displayCount * view.xAxis.increment) / (1000 * 60 * 60)}")
|
// Log.d(TAG, "posX: ${posX / 60 / 60 / 1000}, offsetX = ${view.xAxis.x / (1000 * 60 * 60)}, x = ${entry.x / (1000 * 60 * 60)}, pouet: ${(view.xAxis.x + view.xAxis.displayCount * view.xAxis.increment) / (1000 * 60 * 60)}")
|
||||||
|
|
||||||
// Log.d(
|
Log.d(
|
||||||
// TAG, """
|
TAG, """
|
||||||
// ${posX.toFloat()},
|
${posX},
|
||||||
// $height,
|
$top,
|
||||||
// ${(posX + barWidth).toFloat()},
|
${(posX + barWidth).toFloat()},
|
||||||
// ${space.bottom}""".trimIndent()
|
${drawableSpace.bottom}""".trimIndent()
|
||||||
// )
|
)
|
||||||
|
|
||||||
canvas.drawRect(
|
val right = (posX + barWidth).toFloat().coerceAtMost(drawableSpace.right)
|
||||||
posX.toFloat(),
|
|
||||||
height,
|
if (posX > right) {
|
||||||
(posX + barWidth).toFloat(),
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas.drawRoundRect(
|
||||||
|
posX,
|
||||||
|
top,
|
||||||
|
right,
|
||||||
drawableSpace.bottom,
|
drawableSpace.bottom,
|
||||||
|
// 8f, 8f,
|
||||||
|
32f,
|
||||||
|
32f,
|
||||||
|
0f,
|
||||||
|
0f,
|
||||||
barPaint
|
barPaint
|
||||||
)
|
)
|
||||||
|
|
||||||
canvas.drawText(
|
// handle text display
|
||||||
entry.y.toString(),
|
val text = view.yAxis.onValueFormat(entry.y)
|
||||||
(posX + barWidth / 2).toFloat(),
|
|
||||||
drawableSpace.bottom / 2,
|
|
||||||
view.yAxis.textLabel.apply {
|
|
||||||
textAlign = Paint.Align.CENTER
|
|
||||||
|
|
||||||
|
textPaint.getTextBounds(text, 0, text.length, rect)
|
||||||
|
|
||||||
|
val textLeft = (posX + barWidth / 2).toFloat()
|
||||||
|
|
||||||
|
if (textLeft + rect.width() / 2 > right) {
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val doDisplayIn =
|
||||||
|
rect.height() + 40f < drawableSpace.bottom - top &&
|
||||||
|
rect.width() < barWidth
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
canvas.drawText(
|
||||||
|
text,
|
||||||
|
textLeft,
|
||||||
|
if (doDisplayIn) top + rect.height() + 20f else top - 20f,
|
||||||
|
textPaint
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ sealed class BaseSerie(
|
|||||||
// -+ view.xAxis.increment = one out of display
|
// -+ view.xAxis.increment = one out of display
|
||||||
val minX = view.xAxis.x - view.xAxis.increment
|
val minX = view.xAxis.x - view.xAxis.increment
|
||||||
val maxX =
|
val maxX =
|
||||||
view.xAxis.x + view.xAxis.displayCount * 2 * view.xAxis.increment + view.xAxis.increment
|
view.xAxis.x + view.xAxis.displayCount * view.xAxis.increment + view.xAxis.increment
|
||||||
|
|
||||||
return entries.filter {
|
return entries.filter {
|
||||||
return@filter it.x in minX..maxX
|
return@filter it.x in minX..maxX
|
||||||
|
@ -2,6 +2,7 @@ package com.dzeio.charts.utils
|
|||||||
|
|
||||||
import android.graphics.Canvas
|
import android.graphics.Canvas
|
||||||
import android.graphics.Paint
|
import android.graphics.Paint
|
||||||
|
import android.graphics.RectF
|
||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
fun Canvas.drawDottedLine(
|
fun Canvas.drawDottedLine(
|
||||||
@ -47,3 +48,51 @@ fun Canvas.drawDottedLine(
|
|||||||
// total line length
|
// total line length
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A more customizable drawRoundRect function
|
||||||
|
*/
|
||||||
|
fun Canvas.drawRoundRect(left: Float, top: Float, right: Float, bottom: Float, topLeft: Float, topRight: Float, bottomLeft: Float, bottomRight: Float, paint: Paint) {
|
||||||
|
val maxRound = arrayOf(topLeft, topRight, bottomLeft, bottomRight).maxOf { it }
|
||||||
|
val width = right - left
|
||||||
|
val height = bottom - top
|
||||||
|
|
||||||
|
// draw first/global rect
|
||||||
|
drawRoundRect(left, top, right, bottom, maxRound, maxRound, paint)
|
||||||
|
|
||||||
|
// top left border
|
||||||
|
if (topLeft == 0f) {
|
||||||
|
drawRect(left, top, left + width / 2, top + height / 2, paint)
|
||||||
|
} else {
|
||||||
|
drawRoundRect(left, top, left + width / 2, top + height / 2, topLeft, topLeft, paint)
|
||||||
|
}
|
||||||
|
|
||||||
|
// top right border
|
||||||
|
if (topRight == 0f) {
|
||||||
|
drawRect(right - width / 2, top, right, top + height / 2, paint)
|
||||||
|
} else {
|
||||||
|
drawRoundRect(right - width / 2, top, right, top + height / 2, topRight, topRight, paint)
|
||||||
|
}
|
||||||
|
|
||||||
|
// bottom left border
|
||||||
|
if (bottomLeft == 0f) {
|
||||||
|
drawRect(left, bottom - height / 2, left + width / 2, bottom, paint)
|
||||||
|
} else {
|
||||||
|
drawRoundRect(left, bottom - height / 2, left + width / 2, bottom, bottomLeft, bottomLeft, paint)
|
||||||
|
}
|
||||||
|
|
||||||
|
// bottom right border
|
||||||
|
if (bottomRight == 0f) {
|
||||||
|
drawRect(right - width / 2, bottom - height / 2, right, bottom, paint)
|
||||||
|
} else {
|
||||||
|
drawRoundRect(right - width / 2, bottom - height / 2, right, bottom, bottomRight, bottomRight, paint)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A more customizable drawRoundRect function
|
||||||
|
*/
|
||||||
|
fun Canvas.drawRoundRect(rect: RectF, topLeft: Float, topRight: Float, bottomLeft: Float, bottomRight: Float, paint: Paint) {
|
||||||
|
drawRoundRect(rect.left, rect.top, rect.right, rect.bottom, topLeft, topRight, bottomLeft, bottomRight, paint)
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user