1
0
mirror of https://github.com/dzeiocom/OpenHealth.git synced 2025-04-23 03:12:14 +00:00

fix: label not correctly positionned

This commit is contained in:
Florian Bouillon 2022-08-22 17:50:38 +02:00
parent 57eef94f31
commit 07d150968e
10 changed files with 191 additions and 95 deletions

View File

@ -47,9 +47,42 @@ class StepsHomeFragment :
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 ->
adapter.set(list)
@ -68,34 +101,12 @@ class StepsHomeFragment :
// )
// 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 {
return@map Entry(it.timestamp.toDouble(), it.value.toFloat())
} as ArrayList<Entry>
chart.xAxis.apply {
increment = (1000 * 60 * 60).toDouble()
displayCount = 24 * 7
x = serie.entries.first().x
}
chart.xAxis.x = serie.entries.first().x
// chart.xAxis.onValueFormat = onValueFormat@{
// val formatter = DateFormat.getDateTimeInstance(

View File

@ -2,11 +2,7 @@ package com.dzeio.openhealth.ui.weight
import android.content.SharedPreferences
import android.os.Bundle
import android.view.LayoutInflater
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
import android.view.*
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.preference.PreferenceManager
@ -37,6 +33,7 @@ class ListWeightFragment :
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
// FIXME: deprecated
setHasOptionsMenu(true)
if (viewModel.goalWeight != null) {

View File

@ -50,9 +50,12 @@ class ChartView @JvmOverloads constructor(context: Context?, attrs: AttributeSet
}, debugStrokePaint)
}
// right distance from the yAxis
val rightDistance = yAxis.onDraw(canvas)
// chart draw rectangle
rect.apply {
set(0f, 0f, width.toFloat(), height.toFloat())
set(0f, 8f, width.toFloat() - 16f - rightDistance, height.toFloat() - 16f)
}
for (serie in series) {

View File

@ -29,7 +29,7 @@ interface ChartViewInterface {
var series: ArrayList<SerieInterface>
/**
* refresh EVERYTHING
* refresh the chart
*/
fun refresh()
}

View File

@ -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
}
}
}

View File

@ -3,27 +3,37 @@ package com.dzeio.charts.axis
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.Rect
import com.dzeio.charts.ChartViewInterface
import com.dzeio.charts.utils.drawDottedLine
class YAxis(
private val view: ChartViewInterface
) : YAxisInterface {
override var enabled = false
override var enabled = true
override val textLabel = Paint().apply {
isAntiAlias = true
color = Color.parseColor("#FC496D")
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
private var min: Float? = null
private var max: Float? = null
private val rect = Rect()
override fun setYMin(yMin: Float?): YAxisInterface {
min = yMin
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 max = getYMax() - min
val top = drawLocation.top
val bottom = drawLocation.bottom
val top = 0
val bottom = canvas.height.toFloat()
var maxWidth = 0f
val increment = (bottom - top) / labelCount
val valueIncrement = (max - min) / 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(
(valueIncrement * (labelCount + 1)).toString(),
bottom - (index + 1) * increment,
drawLocation.right,
text,
canvas.width - rect.width().toFloat(),
posY + rect.height() + 8f,
textLabel
)
canvas.drawDottedLine(0f, posY, canvas.width.toFloat(), posY, 40f, linePaint)
}
TODO("IDK if it works tbh")
return maxWidth
}
}

View File

@ -2,7 +2,6 @@ package com.dzeio.charts.axis
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
sealed interface YAxisInterface {
@ -52,7 +51,14 @@ sealed interface YAxisInterface {
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
}

View File

@ -1,10 +1,9 @@
package com.dzeio.charts.series
import android.graphics.Canvas
import android.graphics.Color
import android.graphics.Paint
import android.graphics.RectF
import android.graphics.*
import android.util.Log
import com.dzeio.charts.ChartView
import com.dzeio.charts.utils.drawRoundRect
class BarSerie(
private val view: ChartView
@ -19,6 +18,15 @@ class BarSerie(
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) {
val spacing = drawableSpace.width() / view.xAxis.displayCount / 10
val barWidth = drawableSpace.width() / view.xAxis.displayCount - spacing
@ -30,38 +38,61 @@ class BarSerie(
for (entry in displayedEntries) {
// calculated height in percent from 0 to 100
val height = (1 - entry.y / max) * drawableSpace.height()
// -1.945763981752553E-21
// 2.103653925902835E-21
val posX = view.xAxis.getPositionOnRect(entry, drawableSpace) - view.xAxis.getXOffset(drawableSpace) - canvas.width
val top = (1 - entry.y / max) * drawableSpace.height()
val posX = (view.xAxis.getPositionOnRect(entry, drawableSpace) - view.xAxis.getXOffset(drawableSpace)).toFloat()
// 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, "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.toFloat()},
// $height,
// ${(posX + barWidth).toFloat()},
// ${space.bottom}""".trimIndent()
// )
Log.d(
TAG, """
${posX},
$top,
${(posX + barWidth).toFloat()},
${drawableSpace.bottom}""".trimIndent()
)
canvas.drawRect(
posX.toFloat(),
height,
(posX + barWidth).toFloat(),
val right = (posX + barWidth).toFloat().coerceAtMost(drawableSpace.right)
if (posX > right) {
continue
}
canvas.drawRoundRect(
posX,
top,
right,
drawableSpace.bottom,
// 8f, 8f,
32f,
32f,
0f,
0f,
barPaint
)
canvas.drawText(
entry.y.toString(),
(posX + barWidth / 2).toFloat(),
drawableSpace.bottom / 2,
view.yAxis.textLabel.apply {
textAlign = Paint.Align.CENTER
// handle text display
val text = view.yAxis.onValueFormat(entry.y)
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
)
}
}

View File

@ -22,7 +22,7 @@ sealed class BaseSerie(
// -+ view.xAxis.increment = one out of display
val minX = view.xAxis.x - view.xAxis.increment
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@filter it.x in minX..maxX

View File

@ -2,6 +2,7 @@ package com.dzeio.charts.utils
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.RectF
import kotlin.math.sqrt
fun Canvas.drawDottedLine(
@ -47,3 +48,51 @@ fun Canvas.drawDottedLine(
// 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)
}