Closed
Description
I've been experimenting with using SyncFusion flutter charts with a data stream that has many nulls and is also not close to 0.
I wrote some code to improve the current EmptyPointMode.average
handling by not just looking at the neighbor one to the left or right of an empty point, but iterating the entire list of points and only dividing by 2 if it's actually averaging between two points:
case EmptyPointMode.average:
double lastNonNullBefore = null;
for(var i = pointIndex - 1; i >= 0; i--) {
if(series._dataPoints[i].y != null) {
lastNonNullBefore = series._dataPoints[i].y;
break;
}
}
double firstNonNullAfter = null;
for(var i = pointIndex + 1; i < series._dataPoints.length; i++) {
if(series._dataPoints[i].y != null) {
firstNonNullAfter = series._dataPoints[i].y;
break;
}
}
if (lastNonNullBefore != null && firstNonNullAfter != null) {
series._dataPoints[pointIndex].y = (lastNonNullBefore + firstNonNullAfter) / 2;
} else if (lastNonNullBefore != null) {
series._dataPoints[pointIndex].y = lastNonNullBefore;
} else if (firstNonNullAfter != null) {
series._dataPoints[pointIndex].y = firstNonNullAfter;
} else {
series._dataPoints[pointIndex].y = 0.0;
}
series._dataPoints[pointIndex].isEmpty = true;
break;
Here the full diff:
Index: lib/src/chart/utils/helper.dart
<+>UTF-8
===================================================================
--- lib/src/chart/utils/helper.dart
+++ lib/src/chart/utils/helper.dart
@@ -989,24 +989,28 @@
series._dataPoints[pointIndex].y = 0;
break;
case EmptyPointMode.average:
- if (pointIndex == 0) {
- ///Check the first point is null
- pointIndex == series._dataPoints.length - 1
- ?
- ///Check the series contains single point with null value
- series._dataPoints[pointIndex].y = 0
- : series._dataPoints[pointIndex].y =
- ((series._dataPoints[pointIndex + 1].y) ?? 0) / 2;
- } else if (pointIndex == series._dataPoints.length - 1) {
- ///Check the last point is null
- series._dataPoints[pointIndex].y =
- ((series._dataPoints[pointIndex - 1].y) ?? 0) / 2;
- } else {
- series._dataPoints[pointIndex].y =
- (((series._dataPoints[pointIndex - 1].y) ?? 0) +
- ((series._dataPoints[pointIndex + 1].y) ?? 0)) /
- 2;
+ double lastNonNullBefore = null;
+ for(var i = pointIndex - 1; i >= 0; i--) {
+ if(series._datapoints[i].y != null) {
+ lastNonNullBefore = series._datapoints[i].y;
+ break;
+ }
+ }
+ double firstNonNullAfter = null;
+ for(var i = pointIndex + 1; i < series._dataPoints.length; i++) {
+ if(series._dataPoints[i].y != null) {
+ firstNonNullAfter = series._dataPoints[i].y;
+ break;
+ }
+ }
+
+ if (lastNonNullBefore != null && firstNonNullAfter != null) {
+ series._dataPoints[pointIndex].y = (lastNonNullBefore + firstNonNullAfter) / 2;
+ } else if (lastNonNullBefore != null) {
+ series._dataPoints[pointIndex].y = lastNonNullBefore;
+ } else if (firstNonNullAfter != null) {
+ series._dataPoints[pointIndex].y = firstNonNullAfter;
+ } else {
+ series._dataPoints[pointIndex].y = 0.0;
}
series._dataPoints[pointIndex].isEmpty = true;
break;
Would it be possible to integrate these changes and what's the preferred way to submit PRs to the library itself?
Metadata
Metadata
Assignees
Labels
No labels