1
0
mirror of https://github.com/dzeiocom/OpenHealth.git synced 2025-06-13 09:29:19 +00:00

feat: Moved from in chart to the library one

This commit is contained in:
2023-01-16 10:15:49 +01:00
parent 854195abed
commit 7875271b7e
38 changed files with 140 additions and 1655 deletions

View File

@ -8,6 +8,9 @@ import com.dzeio.openhealth.core.BaseViewHolder
import com.dzeio.openhealth.data.food.Food
import com.dzeio.openhealth.databinding.ItemFoodBinding
import com.dzeio.openhealth.utils.DownloadImageTask
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlin.math.roundToInt
@ -23,6 +26,11 @@ class FoodAdapter : BaseAdapter<Food, ItemFoodBinding>() {
item: Food,
position: Int
) {
CoroutineScope(Dispatchers.IO).launch {
}
// Download remote picture
DownloadImageTask(holder.binding.productImage).execute(item.image)

View File

@ -1,5 +1,6 @@
package com.dzeio.openhealth.data.food
import android.util.Log
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.dzeio.openhealth.data.openfoodfact.OFFProduct
@ -63,7 +64,11 @@ data class Food(
/**
* Transform an OpenFoodFact product to use for our Database
*/
fun fromOpenFoodFact(food: OFFProduct, quantity: Float? = null): Food {
fun fromOpenFoodFact(food: OFFProduct, quantity: Float? = null): Food? {
// filter out foods that we can't use in the app
if (food.name == null || ((food.servingSize == null || food.servingSize == "") && (food.quantity == null || food.quantity == "") && food.servingQuantity == null && food.productQuantity == null)) {
return null
}
// try to know how much was eaten by the user if not said
var eaten = quantity ?: food.servingQuantity ?: food.productQuantity ?: 0f
@ -72,10 +77,13 @@ data class Food(
eaten = food.servingQuantity!!
} else if (food.productQuantity != null && food.productQuantity != 0f) {
eaten = food.productQuantity!!
} else if (food.servingSize != null || food.quantity != null) {
Log.d("pouet", ".${food.servingSize ?: food.quantity}. .${(food.servingSize ?: food.quantity)!!.replace(Regex(" +\\w+$"), "")}. ${food}")
eaten = (food.servingSize ?: food.quantity)!!.trim().replace(Regex(" +\\w+$"), "").toInt().toFloat()
}
}
return Food(
name = food.name,
name = food.name!!,
// do some slight edit on the serving to remove strange entries like `100 g`
serving = (food.servingSize ?: food.quantity ?: "unknown").replace(Regex(" +"), ""),
quantity = eaten,

View File

@ -13,7 +13,7 @@ data class OFFProduct(
* the product name
*/
@SerializedName("product_name")
var name: String,
var name: String?,
/**
* the size of a serving

View File

@ -4,7 +4,7 @@ import android.graphics.Color
import android.view.View
import com.dzeio.openhealth.data.weight.Weight
import com.dzeio.openhealth.units.Units
import com.dzeio.openhealth.utils.GraphUtils
import com.dzeio.openhealth.utils.ChartUtils
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.components.LimitLine
import com.github.mikephil.charting.components.YAxis
@ -29,7 +29,7 @@ object WeightChart {
goal: Float?,
limit: Boolean = true
) {
GraphUtils.lineChartSetup(
ChartUtils.lineChartSetup(
chart,
MaterialColors.getColor(
view,
@ -84,7 +84,7 @@ object WeightChart {
)
}
val rawData = GraphUtils.lineDataSet(
val rawData = ChartUtils.lineDataSet(
LineDataSet(
data.mapIndexed { _, weight ->
return@mapIndexed Entry(
@ -98,7 +98,7 @@ object WeightChart {
axisDependency = YAxis.AxisDependency.RIGHT
}
val averageData = GraphUtils.lineDataSet(LineDataSet(averageYs, "Average")).apply {
val averageData = ChartUtils.lineDataSet(LineDataSet(averageYs, "Average")).apply {
axisDependency = YAxis.AxisDependency.RIGHT
color = Color.GREEN
}

View File

@ -8,6 +8,7 @@ import com.dzeio.openhealth.data.food.FoodRepository
import com.dzeio.openhealth.data.openfoodfact.OpenFoodFactService
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.launch
import java.util.ArrayList
import javax.inject.Inject
@HiltViewModel
@ -23,9 +24,10 @@ class SearchFoodDialogViewModel @Inject internal constructor(
val product = response.body()
if (product != null) {
items.postValue(product.products
.filter { it.name != null }
.map { Food.fromOpenFoodFact(it) }
items.postValue(
product.products
.map { Food.fromOpenFoodFact(it) }
.filter { it != null } as List<Food>
)
}
}

View File

@ -17,7 +17,7 @@ import com.dzeio.openhealth.graphs.WeightChart
import com.dzeio.openhealth.ui.weight.WeightDialog
import com.dzeio.openhealth.units.Units
import com.dzeio.openhealth.utils.DrawUtils
import com.dzeio.openhealth.utils.GraphUtils
import com.dzeio.openhealth.utils.ChartUtils
import com.google.android.material.color.MaterialColors
import dagger.hilt.android.AndroidEntryPoint
import kotlin.math.max
@ -47,7 +47,6 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
/**
* Water Intake
*/
binding.fragmentHomeWaterAdd.setOnClickListener {
val water = viewModel.water.value
if (water == null || !water.isToday()) {
@ -91,7 +90,7 @@ class HomeFragment : BaseFragment<HomeViewModel, FragmentHomeBinding>(HomeViewMo
}
// Make a line Chart using the graph library
GraphUtils.lineChartSetup(
ChartUtils.lineChartSetup(
binding.weightGraph,
MaterialColors.getColor(
requireView(),

View File

@ -11,7 +11,7 @@ import com.dzeio.openhealth.Application
import com.dzeio.openhealth.adapters.StepsAdapter
import com.dzeio.openhealth.core.BaseFragment
import com.dzeio.openhealth.databinding.FragmentStepsHomeBinding
import com.google.android.material.color.MaterialColors
import com.dzeio.openhealth.utils.ChartUtils
import dagger.hilt.android.AndroidEntryPoint
import java.text.DateFormat
import java.util.Calendar
@ -53,46 +53,16 @@ class StepsHomeFragment :
val chart = binding.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
)
}
val errorColor = MaterialColors.getColor(
requireView(),
com.google.android.material.R.attr.colorError
)
val serie = BarSerie(chart)
chart.apply {
series = arrayListOf(serie)
// debug = true
ChartUtils.materielTheme(chart, requireView())
yAxis.apply {
textLabel.color = MaterialColors.getColor(
requireView(),
com.google.android.material.R.attr.colorOnPrimaryContainer
)
linePaint.color = MaterialColors.getColor(
requireView(),
com.google.android.material.R.attr.colorOnPrimaryContainer
)
goalLinePaint.color = errorColor
//
onValueFormat = { value -> "${value.toInt()}" }
}
xAxis.apply {
dataWidth = 604800000.0
textPaint.color = MaterialColors.getColor(
requireView(),
com.google.android.material.R.attr.colorOnPrimaryContainer
)
textPaint.textSize = 32f
onValueFormat = onValueFormat@{
val formatter = DateFormat.getDateTimeInstance(
@ -107,8 +77,10 @@ class StepsHomeFragment :
}
viewModel.goal.observe(viewLifecycleOwner) {
chart.yAxis.setGoalLine(it?.toFloat())
chart.refresh()
if (it != null) {
chart.yAxis.addLine(it.toFloat())
chart.refresh()
}
}
viewModel.items.observe(viewLifecycleOwner) { list ->
@ -118,16 +90,8 @@ class StepsHomeFragment :
return@observe
}
// chart.animation.enabled = false
// chart.animation.refreshRate = 60
// chart.animation.duration = 300
// chart.scroller.zoomEnabled = false
// chart.xAxis.labels.size = 32f
val entries: HashMap<Long, Entry> = HashMap()
list.forEach {
@ -138,7 +102,7 @@ class StepsHomeFragment :
cal.set(Calendar.AM_PM, Calendar.AM)
val ts = cal.timeInMillis
if (!entries.containsKey(ts)) {
entries[ts] = Entry((ts).toDouble(), 0F, errorColor)
entries[ts] = Entry((ts).toDouble(), 0F, chart.yAxis.goalLinePaint.color)
}
entries[ts]!!.y += it.value.toFloat()

View File

@ -6,15 +6,16 @@ import android.view.View
import android.view.ViewGroup
import androidx.navigation.fragment.findNavController
import androidx.recyclerview.widget.LinearLayoutManager
import com.dzeio.charts.Entry
import com.dzeio.charts.series.BarSerie
import com.dzeio.openhealth.adapters.WaterAdapter
import com.dzeio.openhealth.core.BaseFragment
import com.dzeio.openhealth.databinding.FragmentMainWaterHomeBinding
import com.dzeio.openhealth.utils.GraphUtils
import com.github.mikephil.charting.data.BarData
import com.github.mikephil.charting.data.BarDataSet
import com.github.mikephil.charting.data.BarEntry
import com.google.android.material.color.MaterialColors
import com.dzeio.openhealth.utils.ChartUtils
import dagger.hilt.android.AndroidEntryPoint
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@AndroidEntryPoint
class WaterHomeFragment :
@ -45,39 +46,45 @@ class WaterHomeFragment :
val chart = binding.chart
GraphUtils.barChartSetup(
chart,
MaterialColors.getColor(
requireView(),
com.google.android.material.R.attr.colorPrimary
),
MaterialColors.getColor(
requireView(),
com.google.android.material.R.attr.colorOnBackground
)
)
val serie = BarSerie(chart)
chart.apply {
ChartUtils.materielTheme(chart, requireView())
yAxis.apply {
// onValueFormat
}
xAxis.apply {
dataWidth = 604800000.0
textPaint.textSize = 32f
onValueFormat = onValueFormat@{
return@onValueFormat SimpleDateFormat(
"yyyy-MM-dd",
Locale.getDefault()
).format(Date(it.toLong()))
}
}
}
binding.buttonEditDefaultIntake.setOnClickListener {
findNavController().navigate(WaterHomeFragmentDirections.actionNavWaterHomeToNavWaterSizeDialog())
}
chart.xAxis.valueFormatter = GraphUtils.DateValueFormatter(1000 * 60 * 60 * 24)
viewModel.items.observe(viewLifecycleOwner) { list ->
adapter.set(list)
val dataset = BarDataSet(
list.map {
return@map BarEntry(
(it.timestamp / 1000 / 60 / 60 / 24).toFloat(),
it.value.toFloat()
)
},
""
)
val dataset = list.map {
return@map Entry(
it.timestamp.toDouble(),
it.value.toFloat()
)
}
chart.data = BarData(dataset)
chart.invalidate()
serie.entries = dataset as ArrayList<Entry>
chart.xAxis.x = dataset[0].x
chart.refresh()
}
}
}

View File

@ -1,6 +1,9 @@
package com.dzeio.openhealth.utils
import com.github.mikephil.charting.charts.BarChart
import android.view.View
import com.dzeio.charts.ChartView
import com.dzeio.charts.series.BarSerie
import com.dzeio.charts.series.LineSerie
import com.github.mikephil.charting.charts.BarLineChartBase
import com.github.mikephil.charting.charts.LineChart
import com.github.mikephil.charting.components.AxisBase
@ -11,6 +14,7 @@ import com.github.mikephil.charting.data.Entry
import com.github.mikephil.charting.data.LineDataSet
import com.github.mikephil.charting.formatter.ValueFormatter
import com.github.mikephil.charting.interfaces.datasets.IBarLineScatterCandleBubbleDataSet
import com.google.android.material.color.MaterialColors
import java.text.SimpleDateFormat
import java.util.Date
import java.util.Locale
@ -20,7 +24,7 @@ import java.util.Locale
*
* TODO: migrate to DzeioCharts once it is ready
*/
object GraphUtils {
object ChartUtils {
fun lineChartSetup(chart: LineChart, mainColor: Int, textColor: Int) {
barLineChartSetup(chart, mainColor, textColor)
@ -35,10 +39,6 @@ object GraphUtils {
}
}
fun barChartSetup(chart: BarChart, mainColor: Int, textColor: Int) {
barLineChartSetup(chart, mainColor, textColor)
}
private fun <T : BarLineScatterCandleBubbleData<out IBarLineScatterCandleBubbleDataSet<out Entry>>?> barLineChartSetup(
chart: BarLineChartBase<T>,
mainColor: Int,
@ -101,4 +101,62 @@ object GraphUtils {
// return super.getAxisLabel(value, axis)
}
}
/**
* Apply Material theme to a DzeioChart [ChartView]
*/
fun materielTheme(chart: ChartView, view: View) {
val errorColor = MaterialColors.getColor(
view,
com.google.android.material.R.attr.colorError
)
chart.apply {
yAxis.apply {
textLabel.color = MaterialColors.getColor(
view,
com.google.android.material.R.attr.colorOnPrimaryContainer
)
linePaint.color = MaterialColors.getColor(
view,
com.google.android.material.R.attr.colorOnPrimaryContainer
)
goalLinePaint.color = errorColor
}
xAxis.apply {
textPaint.color = MaterialColors.getColor(
view,
com.google.android.material.R.attr.colorOnPrimaryContainer
)
}
for (serie in series) {
if (serie is BarSerie) {
serie.apply {
barPaint.color = MaterialColors.getColor(
view,
com.google.android.material.R.attr.colorPrimary
)
textPaint.color = MaterialColors.getColor(
view,
com.google.android.material.R.attr.colorOnPrimary
)
}
} else if (serie is LineSerie) {
serie.apply {
linePaint.color = MaterialColors.getColor(
view,
com.google.android.material.R.attr.colorPrimary
)
textPaint.color = MaterialColors.getColor(
view,
com.google.android.material.R.attr.colorOnPrimary
)
}
}
}
}
}
}

View File

@ -22,7 +22,7 @@
<com.github.mikephil.charting.charts.BarChart
<com.dzeio.charts.ChartView
android:id="@+id/chart"
android:layout_width="match_parent"
android:layout_height="200dp"