Program: 111181
Project: 111181
Buggy source:
/** 
 * Should be called after new data is inserted. Will be automatically called, when the view dimensions changed. Calculates various offsets and positions for different overlay features based on the graph settings. After the calculation the Path is generated as a normal path or cubic path (Based on 'egUseCubic' attribute).
 */
@Override protected void onDataChanged(){
  if (!mSeries.isEmpty()) {
    int usableGraphHeight=(int)(mGraphHeight - Utils.dpToPx(1.f));
    int seriesCount=mSeries.size();
    float maxValue=0.f;
    float minValue=Float.MAX_VALUE;
    mNegativeValue=0.f;
    mNegativeOffset=0.f;
    mHasNegativeValues=false;
    for (    ValueLineSeries series : mSeries) {
      for (      ValueLinePoint point : series.getSeries()) {
        if (point.getValue() > maxValue)         maxValue=point.getValue();
        if (point.getValue() < mNegativeValue)         mNegativeValue=point.getValue();
        if (point.getValue() < minValue)         minValue=point.getValue();
      }
    }
    if (mShowStandardValues) {
      for (      StandardValue value : mStandardValues) {
        if (value.getValue() > maxValue)         maxValue=value.getValue();
        if (value.getValue() < mNegativeValue)         mNegativeValue=value.getValue();
        if (value.getValue() < minValue)         minValue=value.getValue();
      }
    }
    if (!mUseDynamicScaling) {
      minValue=0;
    }
 else {
      minValue*=mScalingFactor;
    }
    if (mNegativeValue < 0) {
      mHasNegativeValues=true;
      maxValue+=(mNegativeValue * -1);
      minValue=0;
    }
    float heightMultiplier=usableGraphHeight / (maxValue - minValue);
    if (mHasNegativeValues) {
      mNegativeOffset=(mNegativeValue * -1) * heightMultiplier;
    }
    if (mShowStandardValues) {
      for (      StandardValue value : mStandardValues) {
        value.setY((int)(usableGraphHeight - mNegativeOffset - ((value.getValue() - minValue) * heightMultiplier)));
      }
    }
    for (    ValueLineSeries series : mSeries) {
      int seriesPointCount=series.getSeries().size();
      if (seriesPointCount <= 1) {
        Log.w(LOG_TAG,"String_Node_Str");
      }
 else {
        float widthOffset=(float)mGraphWidth / (float)seriesPointCount;
        widthOffset+=widthOffset / seriesPointCount;
        float currentOffset=0;
        series.setWidthOffset(widthOffset);
        float firstX=currentOffset;
        float firstY=usableGraphHeight - ((series.getSeries().get(0).getValue() - minValue) * heightMultiplier);
        Path path=new Path();
        path.moveTo(firstX,firstY);
        series.getSeries().get(0).setCoordinates(new Point2D(firstX,firstY));
        if (mUseCubic) {
          Point2D P1=new Point2D();
          Point2D P2=new Point2D();
          Point2D P3=new Point2D();
          for (int i=0; i < seriesPointCount - 1; i++) {
            int i3=(seriesPointCount - i) < 3 ? i + 1 : i + 2;
            float offset2=(seriesPointCount - i) < 3 ? mGraphWidth : currentOffset + widthOffset;
            float offset3=(seriesPointCount - i) < 3 ? mGraphWidth : currentOffset + (2 * widthOffset);
            P1.setX(currentOffset);
            P1.setY(usableGraphHeight - ((series.getSeries().get(i).getValue() - minValue) * heightMultiplier));
            P2.setX(offset2);
            P2.setY(usableGraphHeight - ((series.getSeries().get(i + 1).getValue() - minValue) * heightMultiplier));
            Utils.calculatePointDiff(P1,P2,P1,mSecondMultiplier);
            P3.setX(offset3);
            P3.setY(usableGraphHeight - ((series.getSeries().get(i3).getValue() - minValue) * heightMultiplier));
            Utils.calculatePointDiff(P2,P3,P3,mFirstMultiplier);
            currentOffset+=widthOffset;
            series.getSeries().get(i + 1).setCoordinates(new Point2D(P2.getX(),P2.getY()));
            path.cubicTo(P1.getX(),P1.getY(),P2.getX(),P2.getY(),P3.getX(),P3.getY());
          }
        }
 else {
          boolean first=true;
          int count=1;
          for (          ValueLinePoint point : series.getSeries()) {
            if (first) {
              first=false;
              continue;
            }
            currentOffset+=widthOffset;
            if (count == seriesPointCount - 1) {
              if (currentOffset < mGraphWidth) {
                currentOffset=mGraphWidth;
              }
            }
            point.setCoordinates(new Point2D(currentOffset,usableGraphHeight - ((point.getValue() - minValue) * heightMultiplier)));
            path.lineTo(point.getCoordinates().getX(),point.getCoordinates().getY());
            count++;
          }
        }
        if (mUseOverlapFill || seriesCount == 1) {
          path.lineTo(mGraphWidth,usableGraphHeight);
          path.lineTo(0,usableGraphHeight);
          path.lineTo(firstX,firstY);
        }
        series.setPath(path);
      }
    }
    if (!mUseCustomLegend) {
      if (calculateLegendBounds())       Utils.calculateLegendInformation(mSeries.get(0).getSeries(),0,mGraphWidth,mLegendPaint);
    }
    if (mShowIndicator && mSeries.size() == 1) {
      int size=mSeries.get(0).getSeries().size();
      int index;
      if (size > 1) {
        if (size == 3) {
          index=size / 2;
        }
 else {
          index=(size / 2) - 1;
        }
        mFocusedPoint=mSeries.get(0).getSeries().get(index);
        mTouchedArea=mFocusedPoint.getCoordinates();
        calculateValueTextHeight();
      }
    }
  }
  super.onDataChanged();
}

Fixed version (ground truth):
/** 
 * Should be called after new data is inserted. Will be automatically called, when the view dimensions changed. Calculates various offsets and positions for different overlay features based on the graph settings. After the calculation the Path is generated as a normal path or cubic path (Based on 'egUseCubic' attribute).
 */
@Override protected void onDataChanged(){
  if (!mSeries.isEmpty()) {
    int seriesCount=mSeries.size();
    float maxValue=0.f;
    float minValue=Float.MAX_VALUE;
    mNegativeValue=0.f;
    mNegativeOffset=0.f;
    mHasNegativeValues=false;
    for (    ValueLineSeries series : mSeries) {
      for (      ValueLinePoint point : series.getSeries()) {
        if (point.getValue() > maxValue)         maxValue=point.getValue();
        if (point.getValue() < mNegativeValue)         mNegativeValue=point.getValue();
        if (point.getValue() < minValue)         minValue=point.getValue();
      }
    }
    if (mShowStandardValues) {
      for (      StandardValue value : mStandardValues) {
        if (value.getValue() > maxValue)         maxValue=value.getValue();
        if (value.getValue() < mNegativeValue)         mNegativeValue=value.getValue();
        if (value.getValue() < minValue)         minValue=value.getValue();
      }
    }
    if (!mUseDynamicScaling) {
      minValue=0;
    }
 else {
      minValue*=mScalingFactor;
    }
    if (mNegativeValue < 0) {
      mHasNegativeValues=true;
      maxValue+=(mNegativeValue * -1);
      minValue=0;
    }
    float heightMultiplier=mUsableGraphHeight / (maxValue - minValue);
    if (mHasNegativeValues) {
      mNegativeOffset=(mNegativeValue * -1) * heightMultiplier;
    }
    if (mShowStandardValues) {
      for (      StandardValue value : mStandardValues) {
        value.setY((int)(mGraphHeight - mNegativeOffset - ((value.getValue() - minValue) * heightMultiplier)));
      }
    }
    for (    ValueLineSeries series : mSeries) {
      int seriesPointCount=series.getSeries().size();
      if (seriesPointCount <= 1) {
        Log.w(LOG_TAG,"String_Node_Str");
      }
 else {
        float widthOffset=(float)mGraphWidth / (float)seriesPointCount;
        widthOffset+=widthOffset / seriesPointCount;
        float currentOffset=0;
        series.setWidthOffset(widthOffset);
        float firstX=currentOffset;
        float firstY=mGraphHeight - ((series.getSeries().get(0).getValue() - minValue) * heightMultiplier);
        Path path=new Path();
        path.moveTo(firstX,firstY);
        series.getSeries().get(0).setCoordinates(new Point2D(firstX,firstY));
        if (mUseCubic) {
          Point2D P1=new Point2D();
          Point2D P2=new Point2D();
          Point2D P3=new Point2D();
          for (int i=0; i < seriesPointCount - 1; i++) {
            int i3=(seriesPointCount - i) < 3 ? i + 1 : i + 2;
            float offset2=(seriesPointCount - i) < 3 ? mGraphWidth : currentOffset + widthOffset;
            float offset3=(seriesPointCount - i) < 3 ? mGraphWidth : currentOffset + (2 * widthOffset);
            P1.setX(currentOffset);
            P1.setY(mGraphHeight - ((series.getSeries().get(i).getValue() - minValue) * heightMultiplier));
            P2.setX(offset2);
            P2.setY(mGraphHeight - ((series.getSeries().get(i + 1).getValue() - minValue) * heightMultiplier));
            Utils.calculatePointDiff(P1,P2,P1,mSecondMultiplier);
            P3.setX(offset3);
            P3.setY(mGraphHeight - ((series.getSeries().get(i3).getValue() - minValue) * heightMultiplier));
            Utils.calculatePointDiff(P2,P3,P3,mFirstMultiplier);
            currentOffset+=widthOffset;
            series.getSeries().get(i + 1).setCoordinates(new Point2D(P2.getX(),P2.getY()));
            path.cubicTo(P1.getX(),P1.getY(),P2.getX(),P2.getY(),P3.getX(),P3.getY());
          }
        }
 else {
          boolean first=true;
          int count=1;
          for (          ValueLinePoint point : series.getSeries()) {
            if (first) {
              first=false;
              continue;
            }
            currentOffset+=widthOffset;
            if (count == seriesPointCount - 1) {
              if (currentOffset < mGraphWidth) {
                currentOffset=mGraphWidth;
              }
            }
            point.setCoordinates(new Point2D(currentOffset,mGraphHeight - ((point.getValue() - minValue) * heightMultiplier)));
            path.lineTo(point.getCoordinates().getX(),point.getCoordinates().getY());
            count++;
          }
        }
        if (mUseOverlapFill || seriesCount == 1) {
          path.lineTo(mGraphWidth,mGraphHeight);
          path.lineTo(0,mGraphHeight);
          path.lineTo(firstX,firstY);
        }
        series.setPath(path);
      }
    }
    if (!mUseCustomLegend) {
      if (calculateLegendBounds())       Utils.calculateLegendInformation(mSeries.get(0).getSeries(),0,mGraphWidth,mLegendPaint);
    }
    if (mShowIndicator && mSeries.size() == 1) {
      int size=mSeries.get(0).getSeries().size();
      int index;
      if (size > 1) {
        if (size == 3) {
          index=size / 2;
        }
 else {
          index=(size / 2) - 1;
        }
        mFocusedPoint=mSeries.get(0).getSeries().get(index);
        mTouchedArea=mFocusedPoint.getCoordinates();
        calculateValueTextHeight();
      }
    }
    resetZoom();
  }
  super.onDataChanged();
}