diff --git a/app/src/main/kotlin/org/db3/airmq/features/common/chart/AirMQChart.kt b/app/src/main/kotlin/org/db3/airmq/features/common/chart/AirMQChart.kt index 0710bae..a0c1c64 100644 --- a/app/src/main/kotlin/org/db3/airmq/features/common/chart/AirMQChart.kt +++ b/app/src/main/kotlin/org/db3/airmq/features/common/chart/AirMQChart.kt @@ -179,15 +179,17 @@ fun AirMQChart( val innerLeft = with(density) { ChartPaddingLeftDp.toPx() } val innerRight = w - with(density) { ChartPaddingRightDp.toPx() } val innerTop = with(density) { ChartPaddingTopDp.toPx() } + val bottomPaddingPx = with(density) { 12.dp.toPx() } val bottomMarginPx = with(density) { 16.dp.toPx() } - val fakePieceTop = h - bottomMarginPx - 1f - val innerBottomLegacy = h - with(density) { ChartPaddingBottomDp.toPx() } - val fillBottom = if (config.roundCorners) fakePieceTop else innerBottomLegacy + bottomMarginPx + // fillBottom = where the fill extends to (space below line is filled with same color) + // chartBottom = where the line's lowest point plots (keeps thick line inside bounds, padding above fillBottom) + val fillBottom = if (config.roundCorners) h - bottomMarginPx - 1f else h + val chartBottom = fillBottom - bottomPaddingPx val chartWidth = innerRight - innerLeft - val chartHeight = fillBottom - innerTop + val chartHeight = chartBottom - innerTop fun toX(ts: Long) = innerLeft + ((ts - xMin) / rangeX.toFloat()) * chartWidth - fun toY(v: Float) = fillBottom - ((v - yMin) / rangeY) * chartHeight + fun toY(v: Float) = chartBottom - ((v - yMin) / rangeY) * chartHeight drawChartBackground( left = innerLeft, @@ -244,7 +246,7 @@ fun AirMQChart( innerLeft = innerLeft, innerRight = innerRight, innerTop = innerTop, - fillBottom = fillBottom, + chartBottom = chartBottom, config = config, unit = unit, textMeasurer = textMeasurer @@ -264,7 +266,7 @@ fun AirMQChart( innerLeft = innerLeft, innerRight = innerRight, innerTop = innerTop, - fillBottom = fillBottom, + chartBottom = chartBottom, textMeasurer = textMeasurer ) } @@ -520,7 +522,7 @@ private fun DrawScope.drawLabels( innerLeft: Float, innerRight: Float, innerTop: Float, - fillBottom: Float, + chartBottom: Float, config: ChartConfig, unit: String, textMeasurer: androidx.compose.ui.text.TextMeasurer @@ -533,15 +535,15 @@ private fun DrawScope.drawLabels( val pad = with(density) { 8.dp.toPx() } val textLayout = textMeasurer.measure("0", TextStyle(fontSize = LabelTextSizeSp.sp)) val baselineOffset = textLayout.size.height * 0.75f - val chartHeight = fillBottom - innerTop + val chartHeight = chartBottom - innerTop val midY = (maxY + minY) / 2f val midText = formatRounded(midY, rangeY) val midYpos = innerTop + chartHeight / 2f + baselineOffset - val bottomBaseline = fillBottom + baselineOffset + val bottomBaseline = chartBottom + baselineOffset drawTextLabelRightAligned(maxText, innerLeft - pad, innerTop + baselineOffset, labelColor, textMeasurer) drawTextLabelRightAligned(midText, innerLeft - pad, midYpos, labelColor, textMeasurer) drawTextLabelRightAligned(minText, innerLeft - pad, bottomBaseline, labelColor, textMeasurer) - val lastYpos = fillBottom - ((lastY - minY) / rangeY) * chartHeight + val lastYpos = chartBottom - ((lastY - minY) / rangeY) * chartHeight val lastTextLayout = textMeasurer.measure(lastText, TextStyle(fontSize = LabelTextSizeSp.sp)) val lastBaseline = lastYpos - lastTextLayout.size.height / 3f drawTextLabel(lastText, innerRight + pad, lastBaseline, labelColor, textMeasurer) @@ -592,11 +594,11 @@ private fun DrawScope.drawMarker( innerLeft: Float, innerRight: Float, innerTop: Float, - fillBottom: Float, + chartBottom: Float, textMeasurer: androidx.compose.ui.text.TextMeasurer ) { drawLine(config.lineColor, Offset(innerLeft, y), Offset(innerRight, y), strokeWidth = 1f) - drawLine(config.lineColor, Offset(x, innerTop - 16), Offset(x, fillBottom + 16), strokeWidth = 1f) + drawLine(config.lineColor, Offset(x, innerTop - 16), Offset(x, chartBottom + 16), strokeWidth = 1f) drawCircle(config.lineColor, radius = MarkerRadiusPx, center = Offset(x, y)) val valueStr = "${formatRounded(point.value, rangeY)} $unit".trim() diff --git a/app/src/main/kotlin/org/db3/airmq/features/map/MapUiComponents.kt b/app/src/main/kotlin/org/db3/airmq/features/map/MapUiComponents.kt index a3c83c6..48132b8 100644 --- a/app/src/main/kotlin/org/db3/airmq/features/map/MapUiComponents.kt +++ b/app/src/main/kotlin/org/db3/airmq/features/map/MapUiComponents.kt @@ -1,6 +1,7 @@ package org.db3.airmq.features.map import androidx.compose.foundation.background +import androidx.compose.foundation.border import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box @@ -27,6 +28,7 @@ import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.tween import androidx.compose.animation.expandVertically import androidx.compose.animation.shrinkVertically import androidx.compose.runtime.getValue @@ -576,8 +578,8 @@ private fun DeviceSensorDropdown( ) { AnimatedVisibility( visible = isExpanded, - enter = expandVertically(), - exit = shrinkVertically() + enter = expandVertically(animationSpec = tween(durationMillis = 150)), + exit = shrinkVertically(animationSpec = tween(durationMillis = 150)) ) { Surface( modifier = Modifier.fillMaxWidth(), @@ -593,6 +595,7 @@ private fun DeviceSensorDropdown( DeviceSensorDropdownOption( sensorType = sensorType, selected = selectedSensor == sensorType, + showSelectedBorder = isExpanded && selectedSensor == sensorType, onClick = { onSelected(sensorType) isExpanded = false @@ -664,12 +667,17 @@ private fun sensorLabelRes(sensorType: DeviceSensorType): Int = when (sensorType private fun DeviceSensorDropdownOption( sensorType: DeviceSensorType, selected: Boolean, + showSelectedBorder: Boolean, onClick: () -> Unit ) { val textColor = if (selected) Color(0xFF1C1C1C) else Color(0xFF616161) + val borderModifier = if (showSelectedBorder) { + Modifier.border(1.dp, Color(0x61000000), RoundedCornerShape(8.dp)) + } else Modifier Row( modifier = Modifier .fillMaxWidth() + .then(borderModifier) .clickable(onClick = onClick) .padding(horizontal = 16.dp, vertical = 10.dp), verticalAlignment = Alignment.CenterVertically