feat: Scrollable x axis (#1445)

* Started horizontal scrolling for DeviceMetrics. Drawing lines based on the TimeFrame and setting the dp.

* Wrote YAxisLabels(), it will replace the Y labels portion of the ChartOverlay(). The composable works for either side of the graph.

* Wrote HorizontalLinesOverlay(), it will replace the horizontal lines portion of the ChartOverlay().

* Updated the data points to use their actual x values.

* Based the width of the scrollable graph on time.

* Added a date label to the TimeAxisOverlay.
This commit is contained in:
Robert-0410 2024-12-01 02:22:54 -08:00 committed by GitHub
parent 3c581f81a8
commit b3f4929cf4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 330 additions and 90 deletions

View file

@ -21,6 +21,8 @@ import android.app.Application
import android.content.SharedPreferences
import android.net.Uri
import androidx.annotation.StringRes
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
@ -120,6 +122,48 @@ enum class TimeFrame(
} else {
System.currentTimeMillis() / 1000 - this.seconds
}
/**
* The time interval to draw the vertical lines representing
* time on the x-axis.
*
* @return seconds epoch seconds
*/
fun lineInterval(): Long {
return when (this.ordinal) {
TWENTY_FOUR_HOURS.ordinal,
FORTY_EIGHT_HOURS.ordinal ->
TimeUnit.HOURS.toSeconds(1)
ONE_WEEK.ordinal,
TWO_WEEKS.ordinal ->
TimeUnit.DAYS.toSeconds(1)
else ->
TimeUnit.DAYS.toSeconds(7)
}
}
/**
* Calculates the needed [Dp] depending on the amount of time being plotted.
*
* @param time in seconds
*/
fun dp(screenWidth: Int, time: Long): Dp {
val timePerScreen = when (this.ordinal) {
TWENTY_FOUR_HOURS.ordinal,
FORTY_EIGHT_HOURS.ordinal ->
TimeUnit.HOURS.toSeconds(1)
ONE_WEEK.ordinal,
TWO_WEEKS.ordinal ->
TimeUnit.DAYS.toSeconds(1)
else ->
TimeUnit.DAYS.toSeconds(7)
}
val multiplier = time / timePerScreen
val dp = (screenWidth * multiplier).toInt().dp
return dp.takeIf { it != 0.dp } ?: screenWidth.dp
}
}
private fun MeshPacket.hasValidSignal(): Boolean =