Skip to content

Improved EmptyPointMode.average #16

Closed
@nightscape

Description

@nightscape

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions