I'm looking mostly for feedback on a solution of mine. I want to create a pretty line graph where the color of the line is dependent on the Y value, and a change in color at y=0. A loose example of such a graph is:
I was wondering how this can be accomplished on Android using Canvas, Paths, etc. I'm currently using MPAndroidChart to handle most of the dirty work. My solution for the coloring part is shown below.
I'm wondering if there is either a simpler way to do this or more efficient method. The reason why I ask is because this code does live in the onDraw method which should be as lightweight as possible and I am creating a new LinearGradient on every draw which I feel like is very expensive. The reason why I do these calculations on every draw is because I allow the user to zoom in on the graph and scroll it, which means the screen coordinates can always change.
protected void drawCubicBezier(ILineDataSet dataSet) {
...
// Get screen coordinates for min Y value
MPPointD pixelForValues = trans.getPixelForValues(0, minDy);
minDy = (float) pixelForValues.y;
MPPointD.recycleInstance(pixelForValues);
// Get screen coordinates for max Y value
pixelForValues = trans.getPixelForValues(0, maxDy);
maxDy = (float) pixelForValues.y;
MPPointD.recycleInstance(pixelForValues);
// Get screen coordinates for 0 value
pixelForValues = trans.getPixelForValues(0, 0);
float zeroDy = (float) pixelForValues.y;
MPPointD.recycleInstance(pixelForValues);
float range = minDy - maxDy;
float zeroPointNormalized = Math.max((zeroDy - maxDy) / range, 0);
linearGradient = new LinearGradient(
0, maxDy, 0, minDy,
new int[]{Color.RED, Color.RED, Color.BLUE, Color.BLUE},
new float[]{0, zeroPointNormalized, zeroPointNormalized, 1f},
Shader.TileMode.REPEAT);
paint.setShader(linearGradient);
...
mBitmapCanvas.drawPath(cubicPath, paint);
}
