mirror of
https://github.com/oliexdev/openScale.git
synced 2025-09-01 12:23:15 +02:00
Add setting to show measurement type on right Y-axis
This commit is contained in:
@@ -2,7 +2,7 @@
|
|||||||
"formatVersion": 1,
|
"formatVersion": 1,
|
||||||
"database": {
|
"database": {
|
||||||
"version": 7,
|
"version": 7,
|
||||||
"identityHash": "d539026586245a45a135ae5bf3aaf73c",
|
"identityHash": "877ad250be34067d136497a388177415",
|
||||||
"entities": [
|
"entities": [
|
||||||
{
|
{
|
||||||
"tableName": "User",
|
"tableName": "User",
|
||||||
@@ -214,7 +214,7 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"tableName": "MeasurementType",
|
"tableName": "MeasurementType",
|
||||||
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `key` TEXT NOT NULL, `name` TEXT, `color` INTEGER NOT NULL, `icon` TEXT NOT NULL, `unit` TEXT NOT NULL, `inputType` TEXT NOT NULL, `displayOrder` INTEGER NOT NULL, `isDerived` INTEGER NOT NULL, `isEnabled` INTEGER NOT NULL, `isPinned` INTEGER NOT NULL)",
|
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `key` TEXT NOT NULL, `name` TEXT, `color` INTEGER NOT NULL, `icon` TEXT NOT NULL, `unit` TEXT NOT NULL, `inputType` TEXT NOT NULL, `displayOrder` INTEGER NOT NULL, `isDerived` INTEGER NOT NULL, `isEnabled` INTEGER NOT NULL, `isPinned` INTEGER NOT NULL, `isOnRightYAxis` INTEGER NOT NULL)",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"fieldPath": "id",
|
"fieldPath": "id",
|
||||||
@@ -280,6 +280,12 @@
|
|||||||
"columnName": "isPinned",
|
"columnName": "isPinned",
|
||||||
"affinity": "INTEGER",
|
"affinity": "INTEGER",
|
||||||
"notNull": true
|
"notNull": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"fieldPath": "isOnRightYAxis",
|
||||||
|
"columnName": "isOnRightYAxis",
|
||||||
|
"affinity": "INTEGER",
|
||||||
|
"notNull": true
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"primaryKey": {
|
"primaryKey": {
|
||||||
@@ -292,7 +298,7 @@
|
|||||||
],
|
],
|
||||||
"setupQueries": [
|
"setupQueries": [
|
||||||
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
|
||||||
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'd539026586245a45a135ae5bf3aaf73c')"
|
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '877ad250be34067d136497a388177415')"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
@@ -59,7 +59,7 @@ import kotlinx.coroutines.launch
|
|||||||
*/
|
*/
|
||||||
fun getDefaultMeasurementTypes(): List<MeasurementType> {
|
fun getDefaultMeasurementTypes(): List<MeasurementType> {
|
||||||
return listOf(
|
return listOf(
|
||||||
MeasurementType(key = MeasurementTypeKey.WEIGHT, unit = UnitType.KG, color = 0xFFEF2929.toInt(), icon = "ic_weight", isPinned = true, isEnabled = true),
|
MeasurementType(key = MeasurementTypeKey.WEIGHT, unit = UnitType.KG, color = 0xFFEF2929.toInt(), icon = "ic_weight", isPinned = true, isEnabled = true, isOnRightYAxis = true),
|
||||||
MeasurementType(key = MeasurementTypeKey.BMI, color = 0xFFF57900.toInt(), icon = "ic_bmi", isDerived = true, isPinned = true, isEnabled = true),
|
MeasurementType(key = MeasurementTypeKey.BMI, color = 0xFFF57900.toInt(), icon = "ic_bmi", isDerived = true, isPinned = true, isEnabled = true),
|
||||||
MeasurementType(key = MeasurementTypeKey.BODY_FAT, color = 0xFFFFCE44.toInt(), icon = "ic_fat", isPinned = true, isEnabled = true),
|
MeasurementType(key = MeasurementTypeKey.BODY_FAT, color = 0xFFFFCE44.toInt(), icon = "ic_fat", isPinned = true, isEnabled = true),
|
||||||
MeasurementType(key = MeasurementTypeKey.WATER, color = 0xFF8AE234.toInt(), icon = "ic_water", isPinned = true, isEnabled = true),
|
MeasurementType(key = MeasurementTypeKey.WATER, color = 0xFF8AE234.toInt(), icon = "ic_water", isPinned = true, isEnabled = true),
|
||||||
|
@@ -34,7 +34,8 @@ data class MeasurementType(
|
|||||||
val displayOrder: Int = 0,
|
val displayOrder: Int = 0,
|
||||||
val isDerived: Boolean = false,
|
val isDerived: Boolean = false,
|
||||||
val isEnabled : Boolean = true,
|
val isEnabled : Boolean = true,
|
||||||
val isPinned : Boolean = false
|
val isPinned : Boolean = false,
|
||||||
|
val isOnRightYAxis : Boolean = false
|
||||||
){
|
){
|
||||||
/**
|
/**
|
||||||
* Gets the appropriate display name for UI purposes.
|
* Gets the appropriate display name for UI purposes.
|
||||||
|
@@ -18,6 +18,7 @@
|
|||||||
package com.health.openscale.ui.screen.components
|
package com.health.openscale.ui.screen.components
|
||||||
|
|
||||||
import android.text.Layout
|
import android.text.Layout
|
||||||
|
import android.util.Log
|
||||||
import androidx.compose.animation.AnimatedVisibility
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
import androidx.compose.foundation.layout.Box
|
import androidx.compose.foundation.layout.Box
|
||||||
@@ -66,6 +67,7 @@ import com.health.openscale.ui.screen.SharedViewModel
|
|||||||
import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost
|
import com.patrykandpatrick.vico.compose.cartesian.CartesianChartHost
|
||||||
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberAxisGuidelineComponent
|
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberAxisGuidelineComponent
|
||||||
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberBottom
|
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberBottom
|
||||||
|
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberEnd
|
||||||
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberStart
|
import com.patrykandpatrick.vico.compose.cartesian.axis.rememberStart
|
||||||
import com.patrykandpatrick.vico.compose.cartesian.layer.point
|
import com.patrykandpatrick.vico.compose.cartesian.layer.point
|
||||||
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLayer
|
import com.patrykandpatrick.vico.compose.cartesian.layer.rememberLineCartesianLayer
|
||||||
@@ -80,9 +82,12 @@ import com.patrykandpatrick.vico.compose.common.fill
|
|||||||
import com.patrykandpatrick.vico.compose.common.insets
|
import com.patrykandpatrick.vico.compose.common.insets
|
||||||
import com.patrykandpatrick.vico.compose.common.shape.markerCorneredShape
|
import com.patrykandpatrick.vico.compose.common.shape.markerCorneredShape
|
||||||
import com.patrykandpatrick.vico.core.cartesian.Zoom
|
import com.patrykandpatrick.vico.core.cartesian.Zoom
|
||||||
|
import com.patrykandpatrick.vico.core.cartesian.axis.Axis
|
||||||
import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis
|
import com.patrykandpatrick.vico.core.cartesian.axis.HorizontalAxis
|
||||||
import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis
|
import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis
|
||||||
|
import com.patrykandpatrick.vico.core.cartesian.axis.VerticalAxis.ItemPlacer.Companion.count
|
||||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
|
import com.patrykandpatrick.vico.core.cartesian.data.CartesianChartModelProducer
|
||||||
|
import com.patrykandpatrick.vico.core.cartesian.data.CartesianLayerRangeProvider
|
||||||
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
|
import com.patrykandpatrick.vico.core.cartesian.data.CartesianValueFormatter
|
||||||
import com.patrykandpatrick.vico.core.cartesian.data.lineSeries
|
import com.patrykandpatrick.vico.core.cartesian.data.lineSeries
|
||||||
import com.patrykandpatrick.vico.core.cartesian.layer.LineCartesianLayer
|
import com.patrykandpatrick.vico.core.cartesian.layer.LineCartesianLayer
|
||||||
@@ -99,6 +104,8 @@ import java.time.Instant
|
|||||||
import java.time.LocalDate
|
import java.time.LocalDate
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
import java.time.format.DateTimeFormatter
|
import java.time.format.DateTimeFormatter
|
||||||
|
import kotlin.math.ceil
|
||||||
|
import kotlin.math.floor
|
||||||
|
|
||||||
internal val DATE_FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("d MMM")
|
internal val DATE_FORMATTER: DateTimeFormatter = DateTimeFormatter.ofPattern("d MMM")
|
||||||
internal val X_TO_DATE_MAP_KEY = ExtraStore.Key<Map<Float, LocalDate>>() // Key for storing date mapping in chart model
|
internal val X_TO_DATE_MAP_KEY = ExtraStore.Key<Map<Float, LocalDate>>() // Key for storing date mapping in chart model
|
||||||
@@ -390,34 +397,62 @@ fun LineChart(
|
|||||||
return@Column // Exits the Column Composable early
|
return@Column // Exits the Column Composable early
|
||||||
}
|
}
|
||||||
|
|
||||||
// Determine colors for each series, using type's predefined color or gray as fallback.
|
val seriesEntriesForStartAxis = remember(seriesEntries) {
|
||||||
val typeColors = remember(seriesEntries) {
|
seriesEntries.filter { (type, _) ->
|
||||||
seriesEntries.map { (type, _) -> // Index not used here
|
!type.isOnRightYAxis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val typeColorsForStartAxis = remember(seriesEntriesForStartAxis) {
|
||||||
|
seriesEntriesForStartAxis.map { (type, _) ->
|
||||||
|
if (type.color != 0) Color(type.color) else Color.Gray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val seriesEntriesForEndAxis = remember(seriesEntries) {
|
||||||
|
seriesEntries.filter { (type, _) ->
|
||||||
|
type.isOnRightYAxis
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val typeColorsForEndAxis = remember(seriesEntriesForEndAxis) {
|
||||||
|
seriesEntriesForEndAxis.map { (type, _) ->
|
||||||
if (type.color != 0) Color(type.color) else Color.Gray
|
if (type.color != 0) Color(type.color) else Color.Gray
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val modelProducer = remember { CartesianChartModelProducer() }
|
val modelProducer = remember { CartesianChartModelProducer() }
|
||||||
|
|
||||||
// Update the chart model when series data or the date map changes.
|
LaunchedEffect(seriesEntriesForStartAxis, seriesEntriesForEndAxis, xToDatesMapForStore) {
|
||||||
LaunchedEffect(seriesEntries, xToDatesMapForStore) {
|
if (seriesEntriesForStartAxis.isNotEmpty() || seriesEntriesForEndAxis.isNotEmpty()) {
|
||||||
if (seriesEntries.isNotEmpty()) {
|
|
||||||
modelProducer.runTransaction {
|
modelProducer.runTransaction {
|
||||||
lineSeries { // Vico's DSL for defining line series
|
if (seriesEntriesForStartAxis.isNotEmpty()) {
|
||||||
seriesEntries.forEach { (_, sortedDateValuePairs) ->
|
lineSeries {
|
||||||
val xValues = sortedDateValuePairs.map { it.first.toEpochDay().toFloat() }
|
seriesEntriesForStartAxis.forEach { (_, sortedDateValuePairs) ->
|
||||||
val yValues = sortedDateValuePairs.map { it.second }
|
val xValues = sortedDateValuePairs.map { it.first.toEpochDay().toFloat() }
|
||||||
if (xValues.isNotEmpty()) {
|
val yValues = sortedDateValuePairs.map { it.second }
|
||||||
series(x = xValues, y = yValues)
|
if (xValues.isNotEmpty()) {
|
||||||
|
series(x = xValues, y = yValues)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
extras { it[X_TO_DATE_MAP_KEY] = xToDatesMapForStore } // Store date map in model extras
|
|
||||||
|
if (seriesEntriesForEndAxis.isNotEmpty()) {
|
||||||
|
lineSeries {
|
||||||
|
seriesEntriesForEndAxis.forEach { (_, sortedDateValuePairs) ->
|
||||||
|
val xValues = sortedDateValuePairs.map { it.first.toEpochDay().toFloat() }
|
||||||
|
val yValues = sortedDateValuePairs.map { it.second }
|
||||||
|
if (xValues.isNotEmpty()) {
|
||||||
|
series(x = xValues, y = yValues)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
extras { it[X_TO_DATE_MAP_KEY] = xToDatesMapForStore }
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Clear the model if there are no series
|
|
||||||
modelProducer.runTransaction {
|
modelProducer.runTransaction {
|
||||||
lineSeries {} // Empty series
|
lineSeries {}
|
||||||
|
lineSeries {}
|
||||||
extras { it.remove(X_TO_DATE_MAP_KEY) }
|
extras { it.remove(X_TO_DATE_MAP_KEY) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -442,31 +477,75 @@ fun LineChart(
|
|||||||
null // Hide X-axis when showing a single, targeted measurement type
|
null // Hide X-axis when showing a single, targeted measurement type
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val rangeProvider = remember {
|
||||||
|
object : CartesianLayerRangeProvider {
|
||||||
|
override fun getMinY(minY: Double, maxY: Double, extraStore: ExtraStore): Double {
|
||||||
|
val r = maxY - minY
|
||||||
|
return if (r == 0.0) minY - 1.0 else floor(minY - 0.1 * r)
|
||||||
|
}
|
||||||
|
override fun getMaxY(minY: Double, maxY: Double, extraStore: ExtraStore): Double {
|
||||||
|
val r = maxY - minY
|
||||||
|
return if (r == 0.0) maxY + 1.0 else ceil(maxY + 0.1 * r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Conditionally create Y-axis.
|
// Conditionally create Y-axis.
|
||||||
val yAxis = if (showYAxis) {
|
val startYAxis = if (showYAxis) {
|
||||||
VerticalAxis.rememberStart(
|
VerticalAxis.rememberStart(valueFormatter = yAxisValueFormatter)
|
||||||
valueFormatter = yAxisValueFormatter,
|
} else { null }
|
||||||
// guideline = rememberAxisGuidelineComponent(), // Optionally add Y-axis guidelines
|
|
||||||
|
val endYAxis = if (showYAxis) {
|
||||||
|
VerticalAxis.rememberEnd(valueFormatter = yAxisValueFormatter)
|
||||||
|
} else { null }
|
||||||
|
|
||||||
|
val lineProviderForStartAxis = remember(seriesEntriesForStartAxis, typeColorsForStartAxis) {
|
||||||
|
LineCartesianLayer.LineProvider.series(
|
||||||
|
seriesEntriesForStartAxis.mapIndexedNotNull { index, _ ->
|
||||||
|
if (index < typeColorsForStartAxis.size) {
|
||||||
|
createLineSpec(typeColorsForStartAxis[index], statisticsMode = targetMeasurementTypeId != null)
|
||||||
|
} else null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
val lineLayerForStartAxis = if (seriesEntriesForStartAxis.isNotEmpty()) {
|
||||||
|
rememberLineCartesianLayer(
|
||||||
|
lineProvider = lineProviderForStartAxis,
|
||||||
|
verticalAxisPosition = Axis.Position.Vertical.Start,
|
||||||
|
rangeProvider = rangeProvider
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Define how lines are drawn (color, thickness, etc.)
|
val lineProviderForEndAxis = remember(seriesEntriesForEndAxis, typeColorsForEndAxis) {
|
||||||
val lineProvider = remember(seriesEntries, typeColors) {
|
|
||||||
LineCartesianLayer.LineProvider.series(
|
LineCartesianLayer.LineProvider.series(
|
||||||
seriesEntries.mapIndexedNotNull { index, _ ->
|
seriesEntriesForEndAxis.mapIndexedNotNull { index, _ ->
|
||||||
if (index < typeColors.size) createLineSpec(typeColors[index], statisticsMode = targetMeasurementTypeId != null) else null
|
if (index < typeColorsForEndAxis.size) {
|
||||||
|
createLineSpec(typeColorsForEndAxis[index], statisticsMode = targetMeasurementTypeId != null)
|
||||||
|
} else null
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
val lineLayerForEndAxis = if (seriesEntriesForEndAxis.isNotEmpty()) {
|
||||||
|
rememberLineCartesianLayer(
|
||||||
|
lineProvider = lineProviderForEndAxis,
|
||||||
|
verticalAxisPosition = Axis.Position.Vertical.End,
|
||||||
|
rangeProvider = rangeProvider
|
||||||
|
)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
|
||||||
val lineLayer = rememberLineCartesianLayer(lineProvider = lineProvider)
|
val layers : List<LineCartesianLayer> = remember(lineLayerForStartAxis, lineLayerForEndAxis) {
|
||||||
|
listOfNotNull(lineLayerForStartAxis, lineLayerForEndAxis)
|
||||||
|
}
|
||||||
|
|
||||||
val chart = rememberCartesianChart(
|
val chart = rememberCartesianChart(
|
||||||
lineLayer,
|
layers = layers.toTypedArray(),
|
||||||
startAxis = yAxis, // Y-axis
|
startAxis = startYAxis, // left Y-axis
|
||||||
bottomAxis = xAxis, // X-axis
|
bottomAxis = xAxis, // X-axis
|
||||||
|
endAxis = endYAxis, // right Y-axis
|
||||||
marker = rememberMarker() // Interactive marker for data points
|
marker = rememberMarker() // Interactive marker for data points
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -110,6 +110,7 @@ fun MeasurementTypeDetailScreen(
|
|||||||
var selectedIcon by remember { mutableStateOf(existingType?.icon ?: "ic_weight") } // Default icon
|
var selectedIcon by remember { mutableStateOf(existingType?.icon ?: "ic_weight") } // Default icon
|
||||||
var isEnabled by remember { mutableStateOf(existingType?.isEnabled ?: true) } // Default to true for new types
|
var isEnabled by remember { mutableStateOf(existingType?.isEnabled ?: true) } // Default to true for new types
|
||||||
var isPinned by remember { mutableStateOf(existingType?.isPinned ?: false) } // Default to false for new types
|
var isPinned by remember { mutableStateOf(existingType?.isPinned ?: false) } // Default to false for new types
|
||||||
|
var isOnRightYAxis by remember { mutableStateOf(existingType?.isOnRightYAxis ?: false) }
|
||||||
|
|
||||||
var expandedUnit by remember { mutableStateOf(false) }
|
var expandedUnit by remember { mutableStateOf(false) }
|
||||||
var expandedInputType by remember { mutableStateOf(false) }
|
var expandedInputType by remember { mutableStateOf(false) }
|
||||||
@@ -138,7 +139,8 @@ fun MeasurementTypeDetailScreen(
|
|||||||
isEnabled = isEnabled,
|
isEnabled = isEnabled,
|
||||||
isPinned = isPinned,
|
isPinned = isPinned,
|
||||||
key = existingType?.key ?: MeasurementTypeKey.CUSTOM, // New types are custom
|
key = existingType?.key ?: MeasurementTypeKey.CUSTOM, // New types are custom
|
||||||
isDerived = existingType?.isDerived ?: false // New types are not derived by default
|
isDerived = existingType?.isDerived ?: false, // New types are not derived by default
|
||||||
|
isOnRightYAxis = isOnRightYAxis
|
||||||
)
|
)
|
||||||
|
|
||||||
if (isEdit) {
|
if (isEdit) {
|
||||||
@@ -311,6 +313,13 @@ fun MeasurementTypeDetailScreen(
|
|||||||
onCheckedChange = { isPinned = it }
|
onCheckedChange = { isPinned = it }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OutlinedSettingRow(label = stringResource(R.string.measurement_type_label_on_right_y_axis)) {
|
||||||
|
Switch(
|
||||||
|
checked = isOnRightYAxis,
|
||||||
|
onCheckedChange = { isOnRightYAxis = it }
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Color Picker Dialog
|
// Color Picker Dialog
|
||||||
|
@@ -141,6 +141,7 @@
|
|||||||
<string name="measurement_type_label_unit">Einheit</string>
|
<string name="measurement_type_label_unit">Einheit</string>
|
||||||
<string name="measurement_type_label_input_type">Eingabetyp</string>
|
<string name="measurement_type_label_input_type">Eingabetyp</string>
|
||||||
<string name="measurement_type_label_pinned">Angeheftet</string>
|
<string name="measurement_type_label_pinned">Angeheftet</string>
|
||||||
|
<string name="measurement_type_label_on_right_y_axis">Auf rechter Y-Achse</string>
|
||||||
<string name="content_desc_selected_icon_preview">Vorschau des ausgewählten Symbols</string>
|
<string name="content_desc_selected_icon_preview">Vorschau des ausgewählten Symbols</string>
|
||||||
<string name="content_desc_drag_handle_sort">Sortieren</string>
|
<string name="content_desc_drag_handle_sort">Sortieren</string>
|
||||||
<string name="content_desc_edit_type">Bearbeiten</string>
|
<string name="content_desc_edit_type">Bearbeiten</string>
|
||||||
|
@@ -142,6 +142,7 @@
|
|||||||
<string name="measurement_type_label_unit">Unit</string>
|
<string name="measurement_type_label_unit">Unit</string>
|
||||||
<string name="measurement_type_label_input_type">Input Type</string>
|
<string name="measurement_type_label_input_type">Input Type</string>
|
||||||
<string name="measurement_type_label_pinned">Pinned</string>
|
<string name="measurement_type_label_pinned">Pinned</string>
|
||||||
|
<string name="measurement_type_label_on_right_y_axis">On right Y-axis</string>
|
||||||
<string name="content_desc_selected_icon_preview">Selected icon preview</string>
|
<string name="content_desc_selected_icon_preview">Selected icon preview</string>
|
||||||
<string name="content_desc_drag_handle_sort">Sort</string>
|
<string name="content_desc_drag_handle_sort">Sort</string>
|
||||||
<string name="content_desc_edit_type">Edit</string>
|
<string name="content_desc_edit_type">Edit</string>
|
||||||
|
Reference in New Issue
Block a user