Cleanup ChartView.

- remove clearPaint
- show two series when no data
This commit is contained in:
Jimmy Shih
2012-05-26 11:52:39 -07:00
parent b5c0a005c3
commit a679d96f93
2 changed files with 78 additions and 58 deletions
@@ -93,7 +93,6 @@ public class ChartView extends View {
private final Paint xAxisMarkerPaint; private final Paint xAxisMarkerPaint;
private final Paint gridPaint; private final Paint gridPaint;
private final Paint markerPaint; private final Paint markerPaint;
private final Paint clearPaint;
private final Drawable pointer; private final Drawable pointer;
private final Drawable statisticsMarker; private final Drawable statisticsMarker;
@@ -120,6 +119,7 @@ public class ChartView extends View {
private boolean chartByDistance = true; private boolean chartByDistance = true;
private boolean metricUnits = true; private boolean metricUnits = true;
private boolean reportSpeed = true;
private boolean showPointer = false; private boolean showPointer = false;
/** /**
@@ -201,11 +201,6 @@ public class ChartView extends View {
markerPaint.setColor(context.getResources().getColor(R.color.gray)); markerPaint.setColor(context.getResources().getColor(R.color.gray));
markerPaint.setAntiAlias(false); markerPaint.setAntiAlias(false);
clearPaint = new Paint();
clearPaint.setStyle(Style.FILL);
clearPaint.setColor(context.getResources().getColor(R.color.white));
clearPaint.setAntiAlias(false);
pointer = context.getResources().getDrawable(R.drawable.arrow_180); pointer = context.getResources().getDrawable(R.drawable.arrow_180);
pointer.setBounds(0, 0, pointer.getIntrinsicWidth(), pointer.getIntrinsicHeight()); pointer.setBounds(0, 0, pointer.getIntrinsicWidth(), pointer.getIntrinsicHeight());
@@ -239,25 +234,34 @@ public class ChartView extends View {
* @param value true for by distance, false for by time * @param value true for by distance, false for by time
*/ */
public void setChartByDistance(boolean value) { public void setChartByDistance(boolean value) {
this.chartByDistance = value; chartByDistance = value;
} }
/** /**
* Sets metric units. * Sets metric units.
* *
* @param metricUnits true to use metric units * @param value true to use metric units
*/ */
public void setMetricUnits(boolean metricUnits) { public void setMetricUnits(boolean value) {
this.metricUnits = metricUnits; metricUnits = value;
}
/**
* Sets report speed.
*
* @param value true to report speed
*/
public void setReportSpeed(boolean value) {
reportSpeed = value;
} }
/** /**
* Sets show pointer. * Sets show pointer.
* *
* @param showPointer true to show pointer * @param value true to show pointer
*/ */
public void setShowPointer(boolean showPointer) { public void setShowPointer(boolean value) {
this.showPointer = showPointer; showPointer = value;
} }
/** /**
@@ -501,7 +505,6 @@ public class ChartView extends View {
drawSeriesTitles(canvas); drawSeriesTitles(canvas);
drawXAxis(canvas); drawXAxis(canvas);
canvas.translate(getScrollX(), 0);
drawYAxis(canvas); drawYAxis(canvas);
canvas.restore(); canvas.restore();
@@ -518,8 +521,9 @@ public class ChartView extends View {
* @param canvas the canvas * @param canvas the canvas
*/ */
private void clipToGraphArea(Canvas canvas) { private void clipToGraphArea(Canvas canvas) {
canvas.clipRect(leftBorder + getScrollX(), topBorder, int x = getScrollX() + leftBorder;
leftBorder + effectiveWidth + getScrollX(), topBorder + effectiveHeight); int y = topBorder;
canvas.clipRect(x, y, x + effectiveWidth, y + effectiveHeight);
} }
/** /**
@@ -572,9 +576,9 @@ public class ChartView extends View {
*/ */
private void drawGrid(Canvas canvas) { private void drawGrid(Canvas canvas) {
// X axis grid // X axis grid
ArrayList<Double> intervals = getXIntervals(); ArrayList<Double> xAxisMarkerPositions = getXAxisMarkerPositions(getXAxisInterval());
for (int i = 1; i < intervals.size(); i++) { for (int i = 0; i < xAxisMarkerPositions.size(); i++) {
int x = getX(intervals.get(i)); int x = getX(xAxisMarkerPositions.get(i));
canvas.drawLine(x, topBorder, x, topBorder + effectiveHeight, gridPaint); canvas.drawLine(x, topBorder, x, topBorder + effectiveHeight, gridPaint);
} }
// Y axis grid // Y axis grid
@@ -635,17 +639,18 @@ public class ChartView extends View {
* @param canvas the canvas * @param canvas the canvas
*/ */
private void drawXAxis(Canvas canvas) { private void drawXAxis(Canvas canvas) {
float rightEdge = getX(maxX); int x = getScrollX() + leftBorder;
int y = topBorder + effectiveHeight; int y = topBorder + effectiveHeight;
canvas.drawLine(leftBorder, y, rightEdge, y, axisPaint); canvas.drawLine(x, y, x + effectiveWidth, y, axisPaint);
String label = getXAxisLabel(); String label = getXAxisLabel();
Rect rect = getRect(axisPaint, label); Rect rect = getRect(axisPaint, label);
canvas.drawText(label, rightEdge + spacer, y + ((int) rect.height() / 2), axisPaint); canvas.drawText(label, x + effectiveWidth + spacer, y + ((int) rect.height() / 2), axisPaint);
ArrayList<Double> intervals = getXIntervals(); double interval = getXAxisInterval();
NumberFormat numberFormat = intervals.get(0) < 1 ? X_FRACTION_FORMAT : X_NUMBER_FORMAT; ArrayList<Double> markerPositions = getXAxisMarkerPositions(interval);
for (int i = 1; i < intervals.size(); i++) { NumberFormat numberFormat = interval < 1 ? X_FRACTION_FORMAT : X_NUMBER_FORMAT;
drawXAxisMarker(canvas, intervals.get(i), numberFormat); for (int i = 0; i < markerPositions.size(); i++) {
drawXAxisMarker(canvas, markerPositions.get(i), numberFormat);
} }
} }
@@ -678,11 +683,9 @@ public class ChartView extends View {
} }
/** /**
* Gets the x axis intervals. The first element of the returned array contains * Gets the x axis interval.
* the size of the interval.
*/ */
private ArrayList<Double> getXIntervals() { private double getXAxisInterval() {
ArrayList<Double> intervals = new ArrayList<Double>();
double interval = maxX / zoomLevel / TARGET_X_AXIS_INTERVALS; double interval = maxX / zoomLevel / TARGET_X_AXIS_INTERVALS;
if (interval < 1) { if (interval < 1) {
interval = .5; interval = .5;
@@ -693,15 +696,23 @@ public class ChartView extends View {
} else { } else {
interval = (interval / 10) * 10; interval = (interval / 10) * 10;
} }
intervals.add(interval); return interval;
intervals.add(0d); }
/**
* Gets the x axis marker positions.
*/
private ArrayList<Double> getXAxisMarkerPositions(double interval) {
ArrayList<Double> markers = new ArrayList<Double>();
markers.add(0d);
for (int i = 1; i * interval < maxX; i++) { for (int i = 1; i * interval < maxX; i++) {
intervals.add(i * interval); markers.add(i * interval);
} }
if (intervals.size() < 3) { // At least 2 markers
intervals.add(maxX); if (markers.size() < 2) {
markers.add(maxX);
} }
return intervals; return markers;
} }
/** /**
@@ -710,16 +721,16 @@ public class ChartView extends View {
* @param canvas the canvas * @param canvas the canvas
*/ */
private void drawYAxis(Canvas canvas) { private void drawYAxis(Canvas canvas) {
// Clears the y axis markers. int x = getScrollX() + leftBorder;
canvas.drawRect(0, topBorder, leftBorder, topBorder + effectiveHeight + spacer, clearPaint); int y = topBorder;
canvas.drawLine(leftBorder, topBorder, leftBorder, topBorder + effectiveHeight, axisPaint); canvas.drawLine(x, y, x, y + effectiveHeight, axisPaint);
int x = leftBorder - spacer; int markerXPosition = x - spacer;
for (int i = 0; i < series.length; i++) { for (int i = 0; i < series.length; i++) {
int index = series.length - 1 - i; int index = series.length - 1 - i;
ChartValueSeries chartValueSeries = series[index]; ChartValueSeries chartValueSeries = series[index];
if (chartValueSeries.isEnabled() && chartValueSeries.hasData() || allowIfEmpty(index)) { if (chartValueSeries.isEnabled() && chartValueSeries.hasData() || allowIfEmpty(index)) {
x -= drawYAxisMarkers(chartValueSeries, canvas, x) + spacer; markerXPosition -= drawYAxisMarkers(chartValueSeries, canvas, markerXPosition) + spacer;
} }
} }
} }
@@ -793,11 +804,8 @@ public class ChartView extends View {
for (ChartValueSeries chartValueSeries : series) { for (ChartValueSeries chartValueSeries : series) {
chartValueSeries.getPath().reset(); chartValueSeries.getPath().reset();
} }
drawPaths();
if (!chartData.isEmpty()) { closePaths();
drawPaths();
closePaths();
}
} }
} }
@@ -805,10 +813,9 @@ public class ChartView extends View {
* Draws all paths. * Draws all paths.
*/ */
private void drawPaths() { private void drawPaths() {
// TODO: Come up with a better sampling. boolean[] hasMoved = new boolean[series.length];
// E.g., Math.max(1, (maxZoomLevel - zoomLevel + 1) / 2)
int sampling = 1; for (int i = 0; i < chartData.size(); i++) {
for (int i = 0; i < chartData.size(); i += sampling) {
double[] dataPoint = chartData.get(i); double[] dataPoint = chartData.get(i);
for (int j = 0; j < series.length; j++) { for (int j = 0; j < series.length; j++) {
double value = dataPoint[j + 1]; double value = dataPoint[j + 1];
@@ -819,7 +826,8 @@ public class ChartView extends View {
Path path = chartValueSeries.getPath(); Path path = chartValueSeries.getPath();
int x = getX(dataPoint[0]); int x = getX(dataPoint[0]);
int y = getY(chartValueSeries, value); int y = getY(chartValueSeries, value);
if (i == 0) { if (!hasMoved[j]) {
hasMoved[j] = true;
path.moveTo(x, y); path.moveTo(x, y);
} else { } else {
path.lineTo(x, y); path.lineTo(x, y);
@@ -832,15 +840,14 @@ public class ChartView extends View {
* Closes all paths. * Closes all paths.
*/ */
private void closePaths() { private void closePaths() {
// Close the path.
int yCorner = topBorder + effectiveHeight;
int xCorner = getX(chartData.get(0)[0]);
for (int i = 0; i < series.length; i++) { for (int i = 0; i < series.length; i++) {
ChartValueSeries chartValueSeries = series[i];
Path path = chartValueSeries.getPath();
int first = getFirstPopulatedChartDataIndex(i); int first = getFirstPopulatedChartDataIndex(i);
if (first != -1) { if (first != -1) {
int xCorner = getX(chartData.get(first)[0]);
int yCorner = topBorder + effectiveHeight;
ChartValueSeries chartValueSeries = series[i];
Path path = chartValueSeries.getPath();
// Bottom right corner // Bottom right corner
path.lineTo(getX(chartData.get(chartData.size() - 1)[0]), yCorner); path.lineTo(getX(chartData.get(chartData.size() - 1)[0]), yCorner);
// Bottom left corner // Bottom left corner
@@ -941,7 +948,7 @@ public class ChartView extends View {
int effectiveSpread = chartValueSeries.getInterval() * Y_AXIS_INTERVALS; int effectiveSpread = chartValueSeries.getInterval() * Y_AXIS_INTERVALS;
double percentage = (value - chartValueSeries.getMinMarkerValue()) / effectiveSpread; double percentage = (value - chartValueSeries.getMinMarkerValue()) / effectiveSpread;
int rangeHeight = effectiveHeight - 2 * yAxisOffset; int rangeHeight = effectiveHeight - 2 * yAxisOffset;
return topBorder + yAxisOffset + rangeHeight - (int) (percentage * rangeHeight); return topBorder + yAxisOffset + (int) ((1 - percentage) * rangeHeight);
} }
/** /**
@@ -976,6 +983,18 @@ public class ChartView extends View {
* @param index the index * @param index the index
*/ */
private boolean allowIfEmpty(int index) { private boolean allowIfEmpty(int index) {
return index == ELEVATION_SERIES && chartData.isEmpty(); if (!chartData.isEmpty()) {
return false;
}
switch (index) {
case ELEVATION_SERIES:
return true;
case SPEED_SERIES:
return reportSpeed;
case PACE_SERIES:
return !reportSpeed;
default:
return false;
}
} }
} }
@@ -280,6 +280,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
return false; return false;
} }
reportSpeed = speed; reportSpeed = speed;
chartView.setReportSpeed(reportSpeed);
boolean chartShowSpeed = PreferencesUtils.getBoolean( boolean chartShowSpeed = PreferencesUtils.getBoolean(
getActivity(), R.string.chart_show_speed_key, PreferencesUtils.CHART_SHOW_SPEED_DEFAULT); getActivity(), R.string.chart_show_speed_key, PreferencesUtils.CHART_SHOW_SPEED_DEFAULT);
setSeriesEnabled(ChartView.SPEED_SERIES, chartShowSpeed && reportSpeed); setSeriesEnabled(ChartView.SPEED_SERIES, chartShowSpeed && reportSpeed);