Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions app/src/main/java/com/matedroid/ui/screens/drives/DriveDetailScreen.kt
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,9 @@ import com.matedroid.data.api.models.Units
import com.matedroid.data.repository.WeatherPoint
import com.matedroid.domain.model.UnitFormatter
import com.matedroid.ui.components.AnnotationRange
import com.matedroid.ui.components.BarChartData
import com.matedroid.ui.components.FullscreenLineChart
import com.matedroid.ui.components.InteractiveBarChart
import com.matedroid.ui.theme.CarColorPalettes
import org.osmdroid.config.Configuration
import org.osmdroid.tileprovider.tilesource.TileSourceFactory
Expand Down Expand Up @@ -327,6 +329,11 @@ private fun DriveDetailContent(
fractionToTimeLabel = fractionToTimeLabel
)
}

SpeedHistogramCard(
positions = detail.positions,
units = units
)
}
}

Expand Down Expand Up @@ -781,6 +788,103 @@ private fun ElevationChartCard(
)
}

@Composable
private fun SpeedHistogramCard(
positions: List<DrivePosition>,
units: Units?
) {
val speeds = positions.mapNotNull { it.speed }
if (speeds.size < 2) return

val isImperial = units?.isImperial == true
val bucketSize = if (isImperial) 5 else 10
val speedUnit = UnitFormatter.getSpeedUnit(units)

val histogramData = remember(speeds, bucketSize) {
buildSpeedHistogram(speeds, bucketSize)
}

if (histogramData.isEmpty()) return

Card(
modifier = Modifier.fillMaxWidth(),
colors = CardDefaults.cardColors(
containerColor = MaterialTheme.colorScheme.surface
)
) {
Column(
modifier = Modifier.padding(16.dp)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(bottom = 12.dp)
) {
Icon(
imageVector = Icons.Default.Speed,
contentDescription = null,
modifier = Modifier.size(20.dp),
tint = MaterialTheme.colorScheme.primary
)
Spacer(modifier = Modifier.width(8.dp))
Text(
text = stringResource(R.string.speed_distribution),
style = MaterialTheme.typography.titleMedium,
fontWeight = FontWeight.Bold
)
}

InteractiveBarChart(
data = histogramData,
barColor = MaterialTheme.colorScheme.primary,
showEveryNthLabel = if (histogramData.size > 8) 2 else 1,
valueFormatter = { pct ->
if (pct < 10.0) "%.1f%%".format(pct) else "%.0f%%".format(pct)
},
yAxisFormatter = { pct ->
if (pct < 10.0) "%.1f%%".format(pct) else "%.0f%%".format(pct)
},
modifier = Modifier.fillMaxWidth()
)
}
}
}

/**
* Builds speed histogram data with buckets of [bucketSize] units.
* Returns bar chart data with percentage values.
*
* Note: The TeslaMate API pre-converts speed to the user's unit system,
* so speeds are already in km/h or mph — no conversion needed here.
*/
private fun buildSpeedHistogram(
speeds: List<Int>,
bucketSize: Int
): List<BarChartData> {
if (speeds.isEmpty()) return emptyList()

val minSpeed = (speeds.min() / bucketSize) * bucketSize
val maxSpeed = ((speeds.max() / bucketSize) + 1) * bucketSize
val total = speeds.size.toDouble()

val buckets = mutableListOf<BarChartData>()
var bucketStart = minSpeed
while (bucketStart < maxSpeed) {
val bucketEnd = bucketStart + bucketSize
val count = speeds.count { it >= bucketStart && it < bucketEnd }
val pct = (count / total) * 100.0
buckets.add(
BarChartData(
label = "$bucketStart",
value = pct,
displayValue = if (pct < 10.0) "%.1f%%".format(pct) else "%.0f%%".format(pct)
)
)
bucketStart = bucketEnd
}

return buckets
}

@Composable
private fun ChartCard(
title: String,
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-ca/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@
<string name="power_profile">Perfil de potència</string>
<string name="battery_level">Nivell de bateria</string>
<string name="elevation_profile">Perfil d\'altitud</string>
<!-- Title for the speed distribution histogram in drive details -->
<string name="speed_distribution">Distribució de velocitat</string>

<!-- Weather section -->
<string name="weather_along_way">Temps al llarg del trajecte</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-es/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@
<string name="power_profile">Perfil de potencia</string>
<string name="battery_level">Nivel de batería</string>
<string name="elevation_profile">Perfil de altitud</string>
<!-- Title for the speed distribution histogram in drive details -->
<string name="speed_distribution">Distribución de velocidad</string>

<!-- Weather section -->
<string name="weather_along_way">Clima en el trayecto</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values-it/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@
<string name="power_profile">Profilo potenza</string>
<string name="battery_level">Livello batteria</string>
<string name="elevation_profile">Profilo altitudine</string>
<!-- Title for the speed distribution histogram in drive details -->
<string name="speed_distribution">Distribuzione velocità</string>

<!-- Weather section -->
<string name="weather_along_way">Meteo lungo il percorso</string>
Expand Down
2 changes: 2 additions & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,8 @@
<string name="power_profile">Power Profile</string>
<string name="battery_level">Battery Level</string>
<string name="elevation_profile">Elevation Profile</string>
<!-- Title for the speed distribution histogram in drive details -->
<string name="speed_distribution">Speed Distribution</string>

<!-- Weather section -->
<string name="weather_along_way">Weather along the way</string>
Expand Down
Loading