Skip to content

Commit 5aaac03

Browse files
committed
fix(tokens): prevent zero spike at chart start when data covers full range
The LTTB zero-fill guard (timestamp < firstRealTimestamp → 0.0) fired unconditionally, even when the gap before the first data point was too small to warrant zero-anchoring. For the weekly chart this meant bucket 0 was set to 0 while bucket 1 held the real value, producing a visible spike at the left edge. Tie the zero-fill to the same hasSignificantGap flag that controls zero-anchor injection so small gaps are handled by interpolation instead. Signed-off-by: Brandon McAnsh <git@bmcreations.dev>
1 parent b2341ae commit 5aaac03

1 file changed

Lines changed: 10 additions & 5 deletions

File tree

  • apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/data

apps/flipcash/shared/tokens/src/main/kotlin/com/flipcash/app/tokens/data/AggregationType.kt

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -65,14 +65,18 @@ sealed interface AggregationType {
6565
val duration = now - startTime
6666
val gapThreshold = duration * 0.05 // 5% of the period
6767

68-
val effective = if (
69-
firstRealPoint != null &&
68+
// Only treat the start as a zero-region when the gap before
69+
// the first real data point is significant (> 5 % of the period).
70+
// Small gaps (data starting a few minutes/hours into the window)
71+
// should NOT produce a zero spike at the left edge of the chart.
72+
val hasSignificantGap = firstRealPoint != null &&
7073
firstRealPoint.x > startTime &&
7174
(firstRealPoint.x - startTime) > gapThreshold
72-
) {
75+
76+
val effective = if (hasSignificantGap) {
7377
val zeroAnchors = listOf(
7478
MarketCapPoint(x = startTime, y = 0.0),
75-
MarketCapPoint(x = firstRealPoint.x - 1, y = 0.0),
79+
MarketCapPoint(x = firstRealPoint!!.x - 1, y = 0.0),
7680
)
7781
zeroAnchors + sorted.filter { it.x > 0 }
7882
} else {
@@ -98,7 +102,8 @@ sealed interface AggregationType {
98102
val timestamp = startTime + (bucket * intervalMs) + (intervalMs / 2)
99103
val y = when {
100104
bucket == targetPoints - 1 -> currentValue
101-
timestamp < firstRealTimestamp -> 0.0
105+
// Zero-fill only when there is a genuine gap at the start
106+
hasSignificantGap && timestamp < firstRealTimestamp -> 0.0
102107
else -> interpolateAt(selected, timestamp)
103108
}
104109
MarketCapPoint(x = timestamp, y = y)

0 commit comments

Comments
 (0)