Fix extreme zoom in showing data as missing instead of interpolating the polyline
This commit is contained in:
@@ -3,13 +3,21 @@ import 'dart:collection';
|
||||
import '../proto/messages.pb.dart';
|
||||
import 'packet_buffer.dart';
|
||||
|
||||
/// One column of decimated data. `hasData=false` means no packet contributed
|
||||
/// a value for this channel in the column's time slice.
|
||||
/// One column of decimated data.
|
||||
///
|
||||
/// Tri-state: a column is either
|
||||
/// - `hasData` — at least one packet in the slice carried this channel
|
||||
/// (renders as a line/min-max span),
|
||||
/// - `isGap` — a packet landed in the slice but had no value for this
|
||||
/// channel (renders as hatched missing-data),
|
||||
/// - neither — no packet at all fell in the slice (empty, skipped; the
|
||||
/// polyline interpolates across).
|
||||
class DecimatedColumn {
|
||||
const DecimatedColumn(this.min, this.max, this.hasData);
|
||||
const DecimatedColumn(this.min, this.max, this.hasData, this.isGap);
|
||||
final double min;
|
||||
final double max;
|
||||
final bool hasData;
|
||||
final bool isGap;
|
||||
}
|
||||
|
||||
/// Classification of a missing-data segment.
|
||||
@@ -82,14 +90,18 @@ class Decimator {
|
||||
final mins = List<double>.filled(pixelWidth, double.infinity);
|
||||
final maxs = List<double>.filled(pixelWidth, double.negativeInfinity);
|
||||
final has = List<bool>.filled(pixelWidth, false);
|
||||
final gap = List<bool>.filled(pixelWidth, false);
|
||||
|
||||
for (final p in buffer.iterateRange(startUs, endUs)) {
|
||||
final v = _channelValue(p, channel);
|
||||
if (v == null) continue;
|
||||
final tsUs = p.timestampUs.toInt();
|
||||
var col = ((tsUs - startUs) / pixUs).floor();
|
||||
if (col < 0) col = 0;
|
||||
if (col >= pixelWidth) col = pixelWidth - 1;
|
||||
final v = _channelValue(p, channel);
|
||||
if (v == null) {
|
||||
gap[col] = true;
|
||||
continue;
|
||||
}
|
||||
if (!has[col]) {
|
||||
mins[col] = v;
|
||||
maxs[col] = v;
|
||||
@@ -101,7 +113,9 @@ class Decimator {
|
||||
}
|
||||
return List.generate(
|
||||
pixelWidth,
|
||||
(i) => DecimatedColumn(mins[i], maxs[i], has[i]),
|
||||
// A column with at least one value renders as data even if some other
|
||||
// packet in the same slice was missing the field.
|
||||
(i) => DecimatedColumn(mins[i], maxs[i], has[i], gap[i] && !has[i]),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -136,7 +150,7 @@ class Decimator {
|
||||
final hatched = <({int startPx, int endPx})>[];
|
||||
int? gapStart;
|
||||
for (var i = 0; i < cols.length; i++) {
|
||||
if (!cols[i].hasData) {
|
||||
if (cols[i].isGap) {
|
||||
gapStart ??= i;
|
||||
} else if (gapStart != null) {
|
||||
hatched.add((startPx: gapStart, endPx: i - 1));
|
||||
|
||||
@@ -106,10 +106,14 @@ class ChartPainter extends CustomPainter {
|
||||
bool started = false;
|
||||
for (var i = 0; i < cols.length; i++) {
|
||||
final c = cols[i];
|
||||
if (!c.hasData) {
|
||||
// Real missing-data gap: break the polyline.
|
||||
if (c.isGap) {
|
||||
started = false;
|
||||
continue;
|
||||
}
|
||||
// Empty column (no packet fell here — sub-packet-period zoom). Let the
|
||||
// path interpolate across.
|
||||
if (!c.hasData) continue;
|
||||
final x = xForCol(i);
|
||||
final yMinPx = yForVal(c.max); // Higher value = smaller y.
|
||||
final yMaxPx = yForVal(c.min);
|
||||
|
||||
Reference in New Issue
Block a user