Skip to content

Commit

Permalink
Implemented GraphUtil.createPath
Browse files Browse the repository at this point in the history
  • Loading branch information
Robert-0410 committed Dec 11, 2024
1 parent 57eeb81 commit 1433d06
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ import com.geeksville.mesh.ui.components.CommonCharts.MS_PER_SEC
import com.geeksville.mesh.ui.components.CommonCharts.DATE_TIME_FORMAT
import com.geeksville.mesh.ui.theme.Orange
import com.geeksville.mesh.util.GraphUtil.plotPoint
import java.util.concurrent.TimeUnit
import com.geeksville.mesh.util.GraphUtil.createPath

private val DEVICE_METRICS_COLORS = listOf(Color.Green, Color.Magenta, Color.Cyan)
private const val MAX_PERCENT_VALUE = 100f
Expand Down Expand Up @@ -224,45 +224,25 @@ private fun DeviceMetricsChart(
)
}

// TODO this works to draw lines only according to it's time
// Can this be made into a function that could be reused for other graphs???
/* Battery Line */
var index = 0
var timeBreak = false
while (index < telemetries.size) {
val testPath = Path().apply {
while(index < telemetries.size) {
val telemetry = telemetries[index]
val nextTelemetry = telemetries.getOrNull(index + 1) ?: telemetries.last()

/* Check to see if we have a significant time break between telemetries. */
if (nextTelemetry.time - telemetry.time > TimeUnit.HOURS.toSeconds(2)) { // TODO constant
timeBreak = true
index++
break
}

val x1Ratio = (telemetry.time - oldest.time).toFloat() / timeDiff
val x1 = x1Ratio * width
val y1Ratio = telemetry.deviceMetrics.batteryLevel / MAX_PERCENT_VALUE
val y1 = height - (y1Ratio * height)

val x2Ratio = (nextTelemetry.time - oldest.time).toFloat() / timeDiff
val x2 = x2Ratio * width
val y2Ratio = nextTelemetry.deviceMetrics.batteryLevel / MAX_PERCENT_VALUE
val y2 = height - (y2Ratio * height)

if (timeBreak || index == 0) {
timeBreak = false
moveTo(x1, y1)
}

quadraticTo(x1, y1, (x1 + x2) / 2f, (y1 + y2) / 2f)

index++
}
val path = Path()
index = createPath(
telemetries = telemetries,
index = index,
path = path,
oldestTime = oldest.time,
timeRange = timeDiff,
width = width
) { i ->
val telemetry = telemetries.getOrNull(i) ?: telemetries.last()
val ratio = telemetry.deviceMetrics.batteryLevel / MAX_PERCENT_VALUE
val y = height - (ratio * height)
return@createPath y
}
drawPath(
path = testPath,
path = path,
color = DEVICE_METRICS_COLORS[Device.BATTERY.ordinal],
style = Stroke(
width = dataPointRadius,
Expand Down
58 changes: 57 additions & 1 deletion app/src/main/java/com/geeksville/mesh/util/GraphUtil.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
package com.geeksville.mesh.util

import androidx.compose.ui.graphics.Path
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.drawscope.DrawContext
import com.geeksville.mesh.TelemetryProtos.Telemetry
import java.util.concurrent.TimeUnit

private const val TIME_SEPARATION_THRESHOLD = 2L

object GraphUtil {

Expand All @@ -28,5 +33,56 @@ object GraphUtil {
)
}

// TODO implement drawing line
/**
* Creates a [Path] that could be used to draw a line from the `index` to the end of `telemetries`
* or the last point before a time separation between [Telemetry]s.
*
* @param telemetries data used to create the [Path]
* @param index current place in the [List]
* @param path [Path] that will be used to draw
* @param timeRange The time range for the data set
* @param width of the [DrawContext]
* @param calculateY (`index`) -> `y` coordinate
*/
fun createPath(
telemetries: List<Telemetry>,
index: Int,
path: Path,
oldestTime: Int,
timeRange: Int,
width: Float,
calculateY: (Int) -> Float
): Int {
var i = index
var isNewLine = true
with (path) {
while (i < telemetries.size) {
val telemetry = telemetries[i]
val nextTelemetry = telemetries.getOrNull(i + 1) ?: telemetries.last()

/* Check to see if we have a significant time break between telemetries. */
if (nextTelemetry.time - telemetry.time > TimeUnit.HOURS.toSeconds(TIME_SEPARATION_THRESHOLD)) {
i++
break
}

val x1Ratio = (telemetry.time - oldestTime).toFloat() / timeRange
val x1 = x1Ratio * width
val y1 = calculateY(i)

val x2Ratio = (nextTelemetry.time - oldestTime).toFloat() / timeRange
val x2 = x2Ratio * width
val y2 = calculateY(i + 1)

if (isNewLine || i == 0) {
isNewLine = false
moveTo(x1, y1)
}

quadraticTo(x1, y1, (x1 + x2) / 2f, (y1 + y2) / 2f)
i++
}
}
return i
}
}

0 comments on commit 1433d06

Please sign in to comment.