Skip to content

Commit 3271714

Browse files
committed
Moved data binding from factory to update block to prevent
lifecycle race conditions
1 parent 40e75a2 commit 3271714

File tree

1 file changed

+35
-45
lines changed

1 file changed

+35
-45
lines changed

profile/src/main/java/no/nordicsemi/android/toolbox/profile/view/channelSounding/RecentMeasurementChart.kt

Lines changed: 35 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,12 @@ internal fun RecentMeasurementChart(previousData: List<Float>) {
3434
modifier = Modifier
3535
.fillMaxWidth()
3636
.height(300.dp),
37-
factory = { createLineChartView(isSystemInDarkTheme, it, items) },
38-
update = { updateData(items, it) }
37+
factory = { context ->
38+
createLineChartView(isSystemInDarkTheme, context)
39+
},
40+
update = { chart ->
41+
updateData(items, chart)
42+
}
3943
)
4044
}
4145

@@ -44,7 +48,9 @@ internal fun RecentMeasurementChart(previousData: List<Float>) {
4448
* This ensures the logic is identical for both initial load and updates.
4549
* @return Pair<LineDataSet, LineDataSet>: one for solid segments, one for dashed bridges.
4650
*/
47-
private fun prepareTwoDataSets(points: List<Float>): Pair<LineDataSet, LineDataSet> {
51+
private fun prepareTwoDataSets(points: List<Float>): Pair<LineDataSet, LineDataSet>? {
52+
if (points.isEmpty()) return null
53+
4854
val adjustedPoints = mutableListOf<Float>()
4955
var lastValidValue = points.firstOrNull { it != 0.0f } ?: 0.0f
5056

@@ -58,42 +64,42 @@ private fun prepareTwoDataSets(points: List<Float>): Pair<LineDataSet, LineDataS
5864

5965
val entries = adjustedPoints.mapIndexed { i, v -> Entry(-i.toFloat(), v) }.reversed()
6066

61-
// SOLID BLUE DATASET
62-
val solidColors = mutableListOf<Int>()
63-
for (i in 0 until points.size - 1) {
64-
if (points[i] != 0.0f && points[i + 1] != 0.0f) solidColors.add(customBlue)
65-
else solidColors.add(Color.TRANSPARENT)
67+
// Helper to build colors and guarantee size matches entries
68+
fun getColors(isSolid: Boolean): List<Int> {
69+
val colorList = mutableListOf<Int>()
70+
for (i in 0 until points.size - 1) {
71+
val isMatch = if (isSolid) (points[i] != 0.0f && points[i + 1] != 0.0f)
72+
else (points[i] == 0.0f || points[i + 1] == 0.0f)
73+
colorList.add(if (isMatch) (if (isSolid) customBlue else signalLostColor) else Color.TRANSPARENT)
74+
}
75+
76+
while (colorList.size < entries.size) {
77+
colorList.add(Color.TRANSPARENT)
78+
}
79+
return colorList.reversed()
6680
}
6781

6882
val solidSet = LineDataSet(entries, "Valid Data").apply {
6983
lineWidth = 3f
7084
setDrawValues(false)
7185
setDrawCircles(false)
72-
colors = solidColors.reversed()
73-
}
74-
75-
// DASHED DATASET
76-
val dashedColors = mutableListOf<Int>()
77-
for (i in 0 until points.size - 1) {
78-
if (points[i] == 0.0f || points[i + 1] == 0.0f) dashedColors.add(signalLostColor)
79-
else dashedColors.add(Color.TRANSPARENT)
86+
colors = getColors(true)
8087
}
8188

8289
val dashedSet = LineDataSet(entries, "Gaps").apply {
8390
lineWidth = 2f
8491
setDrawValues(false)
8592
setDrawCircles(false)
86-
colors = dashedColors.reversed()
87-
enableDashedLine(10f, 10f, 0f) // Only this set is dashed
93+
colors = getColors(false)
94+
enableDashedLine(10f, 10f, 0f)
8895
}
8996

9097
return Pair(solidSet, dashedSet)
9198
}
9299

93-
internal fun createLineChartView(
100+
private fun createLineChartView(
94101
isDarkTheme: Boolean,
95102
context: Context,
96-
points: List<Float>
97103
): LineChart {
98104
return LineChart(context).apply {
99105
// General Setup
@@ -161,37 +167,21 @@ internal fun createLineChartView(
161167

162168
setCustom(listOf(validEntry, dashPart1, dashPart2))
163169
}
164-
165-
// Data Processing & Binding
166-
val (solidSet, dashedSet) = prepareTwoDataSets(points)
167-
168-
// Add both sets to LineData.
169-
// Make sure to the order: the last one added is drawn on top.
170-
data = LineData(dashedSet, solidSet)
171170
}
172171
}
173172

174173
private fun updateData(points: List<Float>, chart: LineChart) {
175-
val (newSolid, newDashed) = prepareTwoDataSets(points)
174+
val result = prepareTwoDataSets(points)
176175

177-
chart.data?.let { lineData ->
178-
// We assume index 0 is dashed and index 1 is solid based on creation order
179-
val dashedSet = lineData.getDataSetByIndex(0) as? LineDataSet
180-
val solidSet = lineData.getDataSetByIndex(1) as? LineDataSet
181-
182-
dashedSet?.apply {
183-
values = newDashed.values
184-
colors = newDashed.colors
185-
}
186-
solidSet?.apply {
187-
values = newSolid.values
188-
colors = newSolid.colors
189-
}
190-
191-
lineData.notifyDataChanged()
192-
chart.notifyDataSetChanged()
193-
chart.invalidate()
176+
if (result == null) {
177+
chart.data = null // Clears the chart when no data
178+
} else {
179+
val (newSolid, newDashed) = result
180+
chart.data = LineData(newDashed, newSolid)
194181
}
182+
183+
chart.notifyDataSetChanged()
184+
chart.invalidate()
195185
}
196186

197187
@Preview(showBackground = true)

0 commit comments

Comments
 (0)