Customizations

In the last chapter we've already seen how to add parameters to our custom view. On the graph custom view we're building in this chapter, we could configure, for example, colors, thickness of the lines, size of dots, and so on, but instead we'll focus on other kinds of customizations, for example, inverting the vertical axis, and enabling or disabling the rendering of the bottom and side labels or graph legend. Contrasting with the previous configurations, these will require some additional code tweaks and specific implementations.

Let's start by allowing inverting the vertical axis. Our default implementation will render the smaller values on top and the bigger values at the bottom of our graph. This might not be the expected result, so let's add a way to invert the axis:

private boolean invertVerticalAxis;

public void setInvertVerticalAxis(boolean invertVerticalAxis) {
this.invertVerticalAxis = invertVerticalAxis;
regenerate = true;
postInvalidate();
}

Then, we have to change only how labels are generated and invert, if applicable, the values of the data points. To change the generation of labels, we can do it by simply updating the order of the steps. Instead of getting a number from 0 to 1, we'll invert the process and get a number from 1 to 0:

float maxLabelWidth = 0.f;
if (regenerate) {
for (int i = 0; i <= 10; i++) {
float step;

if (!invertVerticalAxis) {
step = ((float) i / 10.f);
} else {
step = ((float) (10 - i)) / 10.f;
}

float value = step * verticalDelta + minValue;
verticalLabels[i] = decimalFormat.format(value);
backgroundPaint.getTextBounds(verticalLabels[i], 0,
verticalLabels[i].length(), textBoundaries);
if (textBoundaries.width() > maxLabelWidth) {
maxLabelWidth = textBoundaries.width();
}
}
}

To get an inverted value of a data point, if needed, depending on the flag's value, let's add a new method to do so:

private float getDataPoint(int i) { 
    float data = dataPoints[i]; 
    return invertVerticalAxis ? 1.f - data : data; 
} 

Now, instead of getting the data points directly from the array, we should use this method, as it will transparently invert the number if needed.

As we've mentioned before, we've also added a setLabels() method, so labels can also be externally customized.

We can also add a boolean flag to allow or prevent drawing the legend and background lines:

private boolean drawLegend;

public void setDrawLegend(boolean drawLegend) {
this.drawLegend = drawLegend;
regenerate = true;
postInvalidate();
}

Simply check the status of this flag before drawing the background lines and labels.

See the full example in the Example34-Charts folder on the GitHub repository.