Breaking down chart drawing methods as suggested by Sandor.

This commit is contained in:
Rodrigo Damazio
2011-04-30 19:16:13 -03:00
parent c33c2de18b
commit ea47f93bc1
@@ -510,36 +510,77 @@ public class ChartView extends View {
@Override @Override
protected void onDraw(Canvas c) { protected void onDraw(Canvas c) {
synchronized (data) { synchronized (data) {
if (w != c.getWidth() || h != c.getHeight()) { updateEffectiveDimensionsIfChanged(c);
// Dimensions have changed (for example due to orientation change).
w = c.getWidth(); // Keep original state.
h = c.getHeight();
effectiveWidth = Math.max(0, w - leftBorder - RIGHT_BORDER);
effectiveHeight = Math.max(0, h - topBorder - bottomBorder);
setUpPath();
}
c.save(); c.save();
c.drawColor(Color.WHITE); c.drawColor(Color.WHITE);
if (data.size() < 1) {
if (data.isEmpty()) {
// No data, draw only axes
drawXAxis(c); drawXAxis(c);
drawYAxis(c); drawYAxis(c);
c.restore(); c.restore();
return; return;
} }
// Clip to graph drawing space
c.save(); c.save();
clipToGraphSpace(c);
// Draw the grid and the data on it.
drawGrid(c);
drawDataSeries(c);
drawWaypoints(c);
// Go back to full canvas drawing.
c.restore();
// Draw the axes and their labels.
drawAxesAndLabels(c);
// Go back to original state.
c.restore();
// Draw the pointer
if (showPointer) {
drawPointer(c);
}
}
}
private void clipToGraphSpace(Canvas c) {
c.clipRect(leftBorder + 1 + getScrollX(), topBorder + 1, c.clipRect(leftBorder + 1 + getScrollX(), topBorder + 1,
w - RIGHT_BORDER + getScrollX() - 1, h - bottomBorder - 1); w - RIGHT_BORDER + getScrollX() - 1, h - bottomBorder - 1);
}
drawGrid(c); private void drawAxesAndLabels(Canvas c) {
// Draw the axis and labels.
drawXLabels(c);
drawXAxis(c);
drawSeriesTitles(c);
// Draw the data series. c.translate(getScrollX(), 0);
drawYAxis(c);
float density = getContext().getResources().getDisplayMetrics().density;
final int spacer = (int) (5 * density);
int x = leftBorder - spacer;
for (ChartValueSeries cvs : series) { for (ChartValueSeries cvs : series) {
if (cvs.isEnabled() && cvs.hasData()) { if (cvs.isEnabled() && cvs.hasData()) {
cvs.drawPath(c); x -= drawYLabels(cvs, c, x) + spacer;
}
} }
} }
private void drawPointer(Canvas c) {
c.translate(getX(maxX) - pointer.getIntrinsicWidth() / 2,
getY(series[0], data.get(data.size() - 1)[1])
- pointer.getIntrinsicHeight() / 2 - 12);
pointer.draw(c);
}
private void drawWaypoints(Canvas c) {
// Draw the waypoints. // Draw the waypoints.
for (int i = 1; i < waypoints.size(); i++) { for (int i = 1; i < waypoints.size(); i++) {
final Waypoint waypoint = waypoints.get(i); final Waypoint waypoint = waypoints.get(i);
@@ -558,30 +599,13 @@ public class ChartView extends View {
} }
c.restore(); c.restore();
} }
}
c.restore(); private void drawDataSeries(Canvas c) {
// Draw the data series.
// Draw the axis and labels.
drawXLabels(c);
drawXAxis(c);
drawSeriesTitles(c);
c.translate(getScrollX(), 0);
drawYAxis(c);
float density = getContext().getResources().getDisplayMetrics().density;
final int spacer = (int) (5 * density);
int x = leftBorder - spacer;
for (ChartValueSeries cvs : series) { for (ChartValueSeries cvs : series) {
if (cvs.isEnabled() && cvs.hasData()) { if (cvs.isEnabled() && cvs.hasData()) {
x -= drawYLabels(cvs, c, x) + spacer; cvs.drawPath(c);
}
}
c.restore();
if (showPointer && !data.isEmpty()) {
c.translate(getX(maxX) - pointer.getIntrinsicWidth() / 2,
getY(series[0], data.get(data.size() - 1)[1])
- pointer.getIntrinsicHeight() / 2 - 12);
pointer.draw(c);
} }
} }
} }
@@ -603,7 +627,7 @@ public class ChartView extends View {
} }
/** /**
* Sets up the path that is used to draw the histogram in onDraw(). The path * Sets up the path that is used to draw the chart in onDraw(). The path
* needs to be updated any time after the data or histogram dimensions change. * needs to be updated any time after the data or histogram dimensions change.
*/ */
private void setUpPath() { private void setUpPath() {
@@ -611,10 +635,16 @@ public class ChartView extends View {
for (ChartValueSeries cvs : series) { for (ChartValueSeries cvs : series) {
cvs.getPath().reset(); cvs.getPath().reset();
} }
if (data.isEmpty()) {
return; if (!data.isEmpty()) {
drawPath();
closePath();
}
}
} }
/** Actually draws the data points as a path. */
private void drawPath() {
// All of the data points to the respective series. // All of the data points to the respective series.
// TODO: Come up with a better sampling than Math.max(1, (maxZoomLevel - zoomLevel + 1) / 2); // TODO: Come up with a better sampling than Math.max(1, (maxZoomLevel - zoomLevel + 1) / 2);
int sampling = 1; int sampling = 1;
@@ -633,7 +663,10 @@ public class ChartView extends View {
} }
} }
} }
}
/** Closes the drawn path so it looks like a solid graph. */
private void closePath() {
// Close the path. // Close the path.
int yCorner = topBorder + effectiveHeight; int yCorner = topBorder + effectiveHeight;
int xCorner = getX(data.get(0)[0]); int xCorner = getX(data.get(0)[0]);
@@ -652,7 +685,6 @@ public class ChartView extends View {
} }
} }
} }
}
/** /**
* Find the index of the first point which has a series populated. * Find the index of the first point which has a series populated.
@@ -691,10 +723,24 @@ public class ChartView extends View {
float density = getContext().getResources().getDisplayMetrics().density; float density = getContext().getResources().getDisplayMetrics().density;
maxLength = Math.max(maxLength, 1); maxLength = Math.max(maxLength, 1);
leftBorder = (int) (density * (4 + 8 * maxLength)); leftBorder = (int) (density * (4 + 8 * maxLength));
effectiveWidth = w - leftBorder - RIGHT_BORDER;
bottomBorder = (int) (density * BOTTOM_BORDER); bottomBorder = (int) (density * BOTTOM_BORDER);
topBorder = (int) (density * TOP_BORDER); topBorder = (int) (density * TOP_BORDER);
effectiveHeight = h - topBorder - bottomBorder; updateEffectiveDimensions();
}
private void updateEffectiveDimensions() {
effectiveWidth = Math.max(0, w - leftBorder - RIGHT_BORDER);
effectiveHeight = Math.max(0, h - topBorder - bottomBorder);
}
private void updateEffectiveDimensionsIfChanged(Canvas c) {
if (w != c.getWidth() || h != c.getHeight()) {
// Dimensions have changed (for example due to orientation change).
w = c.getWidth();
h = c.getHeight();
updateEffectiveDimensions();
setUpPath();
}
} }
private int getX(double distance) { private int getX(double distance) {
@@ -795,10 +841,6 @@ public class ChartView extends View {
} }
private void drawGrid(Canvas c) { private void drawGrid(Canvas c) {
if (data.isEmpty()) {
return;
}
float rightEdge = getX(maxX); float rightEdge = getX(maxX);
for (int i = 1; i < MAX_INTERVALS; ++i) { for (int i = 1; i < MAX_INTERVALS; ++i) {
int y = i * effectiveHeight / MAX_INTERVALS + topBorder; int y = i * effectiveHeight / MAX_INTERVALS + topBorder;