Real-time updates

In our first plain implementation of our custom view, we've created a method to set the data points but we couldn't modify or update the data. Let's implement some quick changes to be able to dynamically add points. In this implementation, we adjusted the values to the 0 to 1 scale directly on the setDataPoints() method. As we'll provide a method to add new data values, we might get values outside the original minimum and maximum values, invalidating the scale we calculated before.

Let's first store the data in a collection instead of an array, so we can easily add new values:

 

private ArrayList<Float> dataPoints;

public void setDataPoints(float[] originalData) {
ArrayList<Float> array = new ArrayList<>();
for (float data : originalData) {
array.add(data);
}

setDataPoints(array);
}

public void setDataPoints(ArrayList<Float> originalData) {
dataPoints = new ArrayList<Float>();
dataPoints.addAll(originalData);

adjustDataRange();
}

We'll be storing the data in an ArrayList and we've modified the setDataPoints() method in order to be able to do so. Also, we have created the adjustDataRange() method to recalculate the range of the data and trigger a data regeneration and a redraw of our view:

 

private void adjustDataRange() {
minValue = Float.MAX_VALUE;
maxValue = Float.MIN_VALUE;
for (int i = 0; i < dataPoints.size(); i++) {
if (dataPoints.get(i) < minValue) minValue = dataPoints.get(i);
if (dataPoints.get(i) > maxValue) maxValue = dataPoints.get(i);
}

verticalDelta = maxValue - minValue;

regenerate = true;
postInvalidate();
}

The implementation of the addValue() method is quite simple. We add the new data to the ArrayList and if it's inside the current range, we just trigger a regeneration of the graph and a redraw of our view. If it's outside the current range, we call the adjustDataRange() method to adjust all the data to the new range:

public void addValue(float data) {
dataPoints.add(data);

if (data < minValue || data > maxValue) {
adjustDataRange();
} else {
regenerate = true;
postInvalidate();
}
}

We just need to modify the getDataPoint() method to adjust the data to the 0 to 1 range:

private float getDataPoint(int i) { 
    float data = (dataPoints.get(i) - minValue) / verticalDelta; 
    return invertVerticalAxis ? 1.f - data : data; 
} 

If we run the example, we can see we can add new points to the graph and it will adjust automatically. To completely change or update the data, the method setDataPoints() must be called.