forked from upstream-mirrors/OpenTracks
merge heads
This commit is contained in:
@@ -13,9 +13,11 @@
|
|||||||
* License for the specific language governing permissions and limitations under
|
* License for the specific language governing permissions and limitations under
|
||||||
* the License.
|
* the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.google.android.apps.mytracks;
|
package com.google.android.apps.mytracks;
|
||||||
|
|
||||||
import com.google.android.apps.mytracks.stats.ExtremityMonitor;
|
import com.google.android.apps.mytracks.stats.ExtremityMonitor;
|
||||||
|
import com.google.common.annotations.VisibleForTesting;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Canvas;
|
import android.graphics.Canvas;
|
||||||
@@ -26,122 +28,118 @@ import android.graphics.Path;
|
|||||||
import java.text.NumberFormat;
|
import java.text.NumberFormat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class encapsulates meta data about one series of values for a chart.
|
* This class encapsulates the meta data for one series of chart values.
|
||||||
*
|
*
|
||||||
* @author Sandor Dornbush
|
* @author Sandor Dornbush
|
||||||
*/
|
*/
|
||||||
public class ChartValueSeries {
|
public class ChartValueSeries {
|
||||||
|
|
||||||
private final ExtremityMonitor monitor = new ExtremityMonitor();
|
private static final float STROKE_WIDTH = 2f;
|
||||||
private final NumberFormat format;
|
|
||||||
private final Path path = new Path();
|
private final ExtremityMonitor extremityMonitor;
|
||||||
|
private final NumberFormat numberFormat;
|
||||||
|
private final Path path;
|
||||||
private final Paint fillPaint;
|
private final Paint fillPaint;
|
||||||
private final Paint strokePaint;
|
private final Paint strokePaint;
|
||||||
private final Paint labelPaint;
|
private final Paint labelPaint;
|
||||||
private final ZoomSettings zoomSettings;
|
private final YAxisDimension markingInterval;
|
||||||
|
|
||||||
private String title;
|
private String title;
|
||||||
private double min;
|
|
||||||
private double max = 1.0;
|
|
||||||
private int effectiveMax;
|
|
||||||
private int effectiveMin;
|
|
||||||
private double spread;
|
|
||||||
private int interval;
|
|
||||||
private boolean enabled = true;
|
private boolean enabled = true;
|
||||||
|
private int interval = 1;
|
||||||
|
private int effectiveMin = 0;
|
||||||
|
private int effectiveMax = 1;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class controls how effective min/max values of a {@link ChartValueSeries} are calculated.
|
* This class to calculates the y axis dimension, interval, effective min, and
|
||||||
|
* effective max.
|
||||||
*/
|
*/
|
||||||
public static class ZoomSettings {
|
public static class YAxisDimension {
|
||||||
private int intervals;
|
private final int numberOfIntervals;
|
||||||
private final int absoluteMin;
|
private final int absoluteMin;
|
||||||
private final int absoluteMax;
|
private final int absoluteMax;
|
||||||
private final int[] zoomLevels;
|
private final int[] intervalValues;
|
||||||
|
|
||||||
public ZoomSettings(int intervals, int[] zoomLevels) {
|
/**
|
||||||
this.intervals = intervals;
|
* Constructor.
|
||||||
this.absoluteMin = Integer.MAX_VALUE;
|
*
|
||||||
this.absoluteMax = Integer.MIN_VALUE;
|
* @param numberOfIntervals the number of intervals
|
||||||
this.zoomLevels = zoomLevels;
|
* @param absoluteMin the absolute minimum value
|
||||||
checkArgs();
|
* @param absoluteMax the absolute maximum value
|
||||||
}
|
* @param intervalValues the list of interval values
|
||||||
|
*/
|
||||||
public ZoomSettings(int intervals, int absoluteMin, int absoluteMax, int[] zoomLevels) {
|
public YAxisDimension(
|
||||||
this.intervals = intervals;
|
int numberOfIntervals, int absoluteMin, int absoluteMax, int[] intervalValues) {
|
||||||
|
this.numberOfIntervals = numberOfIntervals;
|
||||||
this.absoluteMin = absoluteMin;
|
this.absoluteMin = absoluteMin;
|
||||||
this.absoluteMax = absoluteMax;
|
this.absoluteMax = absoluteMax;
|
||||||
this.zoomLevels = zoomLevels;
|
this.intervalValues = intervalValues;
|
||||||
checkArgs();
|
|
||||||
}
|
|
||||||
|
|
||||||
private void checkArgs() {
|
|
||||||
if (intervals <= 0 || zoomLevels == null || zoomLevels.length == 0) {
|
|
||||||
throw new IllegalArgumentException("Expecing positive intervals and non-empty zoom levels");
|
|
||||||
}
|
|
||||||
for (int i = 1; i < zoomLevels.length; ++i) {
|
|
||||||
if (zoomLevels[i] <= zoomLevels[i - 1]) {
|
|
||||||
throw new IllegalArgumentException("Expecting zoom levels in ascending order");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getIntervals() {
|
|
||||||
return intervals;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAbsoluteMin() {
|
|
||||||
return absoluteMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getAbsoluteMax() {
|
|
||||||
return absoluteMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int[] getZoomLevels() {
|
|
||||||
return zoomLevels;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Calculates the interval between markings given the min and max values.
|
* Gets the y axis dimension. Returns an array of int[3], containing interval, effectiveMin,
|
||||||
* This function attempts to find the smallest zoom level that fits [min,max] after rounding
|
* and effectiveMax.
|
||||||
* it to the current zoom level.
|
*
|
||||||
*
|
* @param min the min value
|
||||||
* @param min the minimum value in the series
|
* @param max the max value
|
||||||
* @param max the maximum value in the series
|
|
||||||
* @return the calculated interval for the given range
|
|
||||||
*/
|
*/
|
||||||
public int calculateInterval(double min, double max) {
|
public int[] getYAxisDimension(double min, double max) {
|
||||||
min = Math.min(min, absoluteMin);
|
min = Math.max(min, absoluteMin);
|
||||||
max = Math.max(max, absoluteMax);
|
max = Math.min(max, absoluteMax);
|
||||||
for (int i = 0; i < zoomLevels.length; ++i) {
|
int interval = 0;
|
||||||
int zoomLevel = zoomLevels[i];
|
int effectiveMin = 0;
|
||||||
int roundedMin = (int)(min / zoomLevel) * zoomLevel;
|
for (int i = 0; i < intervalValues.length; i++) {
|
||||||
if (roundedMin > min) {
|
interval = intervalValues[i];
|
||||||
roundedMin -= zoomLevel;
|
effectiveMin = getEffetiveMin(min, interval);
|
||||||
}
|
double targetInterval = (max - effectiveMin) / numberOfIntervals;
|
||||||
double interval = (max - roundedMin) / intervals;
|
if (interval >= targetInterval) {
|
||||||
if (zoomLevel >= interval) {
|
break;
|
||||||
return zoomLevel;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return zoomLevels[zoomLevels.length - 1];
|
int effectiveMax = getEffectiveMax(max, interval);
|
||||||
|
return new int[] { interval, effectiveMin, effectiveMax };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the effective min value.
|
||||||
|
*
|
||||||
|
* @param min the min value
|
||||||
|
* @param interval the interval
|
||||||
|
*/
|
||||||
|
private int getEffetiveMin(double min, int interval) {
|
||||||
|
int value = (int) (min / interval) * interval;
|
||||||
|
// value > min if min is negative
|
||||||
|
if (value > min) {
|
||||||
|
return value - interval;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the effective max value
|
||||||
|
*
|
||||||
|
* @param max the max value
|
||||||
|
* @param interval the interval
|
||||||
|
*/
|
||||||
|
private int getEffectiveMax(double max, int interval) {
|
||||||
|
return ((int) (max / interval)) * interval + interval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new chart value series.
|
* Constructs a new chart value series.
|
||||||
*
|
*
|
||||||
* @param context The context for the chart
|
* @param context the context
|
||||||
* @param fillColor The paint for filling the chart
|
* @param fillColor the fill color
|
||||||
* @param strokeColor The paint for stroking the outside the chart, optional
|
* @param strokeColor the stroke color
|
||||||
* @param zoomSettings The settings related to zooming
|
* @param yAxisDimension the marking interval
|
||||||
* @param titleId The title ID
|
* @param titleId the title id
|
||||||
*
|
|
||||||
* TODO: Get rid of Context and inject appropriate values instead.
|
|
||||||
*/
|
*/
|
||||||
public ChartValueSeries(
|
public ChartValueSeries(Context context, int fillColor, int strokeColor,
|
||||||
Context context, int fillColor, int strokeColor, ZoomSettings zoomSettings, int titleId) {
|
YAxisDimension yAxisDimension, int titleId) {
|
||||||
this.format = NumberFormat.getIntegerInstance();
|
extremityMonitor = new ExtremityMonitor();
|
||||||
|
numberFormat = NumberFormat.getIntegerInstance();
|
||||||
|
path = new Path();
|
||||||
fillPaint = new Paint();
|
fillPaint = new Paint();
|
||||||
fillPaint.setStyle(Style.FILL);
|
fillPaint.setStyle(Style.FILL);
|
||||||
fillPaint.setColor(context.getResources().getColor(fillColor));
|
fillPaint.setColor(context.getResources().getColor(fillColor));
|
||||||
@@ -151,155 +149,137 @@ public class ChartValueSeries {
|
|||||||
strokePaint.setStyle(Style.STROKE);
|
strokePaint.setStyle(Style.STROKE);
|
||||||
strokePaint.setColor(context.getResources().getColor(strokeColor));
|
strokePaint.setColor(context.getResources().getColor(strokeColor));
|
||||||
strokePaint.setAntiAlias(true);
|
strokePaint.setAntiAlias(true);
|
||||||
// Make a copy of the stroke paint with the default thickness.
|
// Make a copy of the stroke paint with the default thickness
|
||||||
labelPaint = new Paint(strokePaint);
|
labelPaint = new Paint(strokePaint);
|
||||||
strokePaint.setStrokeWidth(2f);
|
strokePaint.setStrokeWidth(STROKE_WIDTH);
|
||||||
} else {
|
} else {
|
||||||
strokePaint = null;
|
strokePaint = null;
|
||||||
labelPaint = fillPaint;
|
labelPaint = fillPaint;
|
||||||
}
|
}
|
||||||
this.zoomSettings = zoomSettings;
|
this.markingInterval = yAxisDimension;
|
||||||
this.title = context.getString(titleId);
|
title = context.getString(titleId);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draws the path of the chart
|
* Returns true if the series has data.
|
||||||
*/
|
*/
|
||||||
public void drawPath(Canvas c) {
|
public boolean hasData() {
|
||||||
c.drawPath(path, fillPaint);
|
return extremityMonitor.hasData();
|
||||||
if (strokePaint != null) {
|
|
||||||
c.drawPath(path, strokePaint);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets this series
|
* Updates the series with a new value.
|
||||||
|
*
|
||||||
|
* @param value the new value
|
||||||
*/
|
*/
|
||||||
public void reset() {
|
public void update(double value) {
|
||||||
monitor.reset();
|
extremityMonitor.update(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates this series with a new value
|
* Gets the number format for the series.
|
||||||
*/
|
*/
|
||||||
public void update(double d) {
|
public NumberFormat getNumberFormat() {
|
||||||
monitor.update(d);
|
return numberFormat;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The interval between markers
|
* Gets the path.
|
||||||
*/
|
*/
|
||||||
public int getInterval() {
|
public Path getPath() {
|
||||||
return interval;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Determines what the min and max of the chart will be.
|
|
||||||
* This will round down and up the min and max respectively.
|
|
||||||
*/
|
|
||||||
public void updateDimension() {
|
|
||||||
if (monitor.getMax() == Double.NEGATIVE_INFINITY) {
|
|
||||||
min = 0;
|
|
||||||
max = 1;
|
|
||||||
} else {
|
|
||||||
min = monitor.getMin();
|
|
||||||
max = monitor.getMax();
|
|
||||||
}
|
|
||||||
min = Math.min(min, zoomSettings.getAbsoluteMin());
|
|
||||||
max = Math.max(max, zoomSettings.getAbsoluteMax());
|
|
||||||
|
|
||||||
this.interval = zoomSettings.calculateInterval(min, max);
|
|
||||||
// Round it up.
|
|
||||||
effectiveMax = ((int) (max / interval)) * interval + interval;
|
|
||||||
// Round it down.
|
|
||||||
effectiveMin = ((int) (min / interval)) * interval;
|
|
||||||
if (min < 0) {
|
|
||||||
effectiveMin -= interval;
|
|
||||||
}
|
|
||||||
spread = effectiveMax - effectiveMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The length of the longest string from the series
|
|
||||||
*/
|
|
||||||
public int getMaxLabelLength() {
|
|
||||||
String minS = format.format(effectiveMin);
|
|
||||||
String maxS = format.format(getMax());
|
|
||||||
return Math.max(minS.length(), maxS.length());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The rounded down minimum value
|
|
||||||
*/
|
|
||||||
public int getMin() {
|
|
||||||
return effectiveMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The rounded up maximum value
|
|
||||||
*/
|
|
||||||
public int getMax() {
|
|
||||||
return effectiveMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The difference between the min and max values in the series
|
|
||||||
*/
|
|
||||||
public double getSpread() {
|
|
||||||
return spread;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The number format for this series
|
|
||||||
*/
|
|
||||||
NumberFormat getFormat() {
|
|
||||||
return format;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return The path for this series
|
|
||||||
*/
|
|
||||||
Path getPath() {
|
|
||||||
return path;
|
return path;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The paint for this series
|
* Gets the label paint.
|
||||||
*/
|
*/
|
||||||
Paint getPaint() {
|
|
||||||
return strokePaint == null ? fillPaint : strokePaint;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Paint getLabelPaint() {
|
public Paint getLabelPaint() {
|
||||||
return labelPaint;
|
return labelPaint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return The title of the series
|
* Gets the title.
|
||||||
*/
|
*/
|
||||||
public String getTitle() {
|
public String getTitle() {
|
||||||
return title;
|
return title;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the title.
|
||||||
|
*
|
||||||
|
* @param title the title
|
||||||
|
*/
|
||||||
public void setTitle(String title) {
|
public void setTitle(String title) {
|
||||||
this.title = title;
|
this.title = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return is this series enabled
|
* Returns true if the series is enabled.
|
||||||
*/
|
*/
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
return enabled;
|
return enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the series enabled flag.
|
* Sets the enabled value.
|
||||||
|
*
|
||||||
|
* @param enabled true to enable
|
||||||
*/
|
*/
|
||||||
public void setEnabled(boolean enabled) {
|
public void setEnabled(boolean enabled) {
|
||||||
this.enabled = enabled;
|
this.enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draws the path on canvas.
|
||||||
|
*
|
||||||
|
* @param canvas the canvas
|
||||||
|
*/
|
||||||
|
public void drawPath(Canvas canvas) {
|
||||||
|
canvas.drawPath(path, fillPaint);
|
||||||
|
if (strokePaint != null) {
|
||||||
|
canvas.drawPath(path, strokePaint);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public boolean hasData() {
|
/**
|
||||||
return monitor.hasData();
|
* Updates the y axis dimension.
|
||||||
|
*/
|
||||||
|
public void updateDimension() {
|
||||||
|
boolean hasData = extremityMonitor.hasData();
|
||||||
|
double min = hasData ? extremityMonitor.getMin() : 0.0;
|
||||||
|
double max = hasData ? extremityMonitor.getMax() : 1.0;
|
||||||
|
int[] dimension = markingInterval.getYAxisDimension(min, max);
|
||||||
|
interval = dimension[0];
|
||||||
|
effectiveMin = dimension[1];
|
||||||
|
effectiveMax = dimension[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the y axis interval value.
|
||||||
|
*/
|
||||||
|
public int getInterval() {
|
||||||
|
return interval;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the minimum value.
|
||||||
|
*/
|
||||||
|
public int getMin() {
|
||||||
|
return effectiveMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the maximum value.
|
||||||
|
*/
|
||||||
|
@VisibleForTesting
|
||||||
|
int getMax() {
|
||||||
|
return effectiveMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the maximum label length.
|
||||||
|
*/
|
||||||
|
public int getMaxLabelLength() {
|
||||||
|
return Math.max(numberFormat.format(getMin()).length(), numberFormat.format(getMax()).length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.apps.mytracks;
|
package com.google.android.apps.mytracks;
|
||||||
|
|
||||||
import com.google.android.apps.mytracks.ChartValueSeries.ZoomSettings;
|
import com.google.android.apps.mytracks.ChartValueSeries.YAxisDimension;
|
||||||
import com.google.android.apps.mytracks.content.Waypoint;
|
import com.google.android.apps.mytracks.content.Waypoint;
|
||||||
import com.google.android.apps.mytracks.stats.ExtremityMonitor;
|
import com.google.android.apps.mytracks.stats.ExtremityMonitor;
|
||||||
import com.google.android.apps.mytracks.util.IntentUtils;
|
import com.google.android.apps.mytracks.util.IntentUtils;
|
||||||
@@ -208,7 +208,7 @@ public class ChartView extends View {
|
|||||||
new ChartValueSeries(context,
|
new ChartValueSeries(context,
|
||||||
R.color.elevation_fill,
|
R.color.elevation_fill,
|
||||||
R.color.elevation_border,
|
R.color.elevation_border,
|
||||||
new ZoomSettings(MAX_INTERVALS,
|
new YAxisDimension(MAX_INTERVALS, Integer.MIN_VALUE, Integer.MAX_VALUE,
|
||||||
new int[] {5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000}),
|
new int[] {5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000}),
|
||||||
R.string.stats_elevation);
|
R.string.stats_elevation);
|
||||||
|
|
||||||
@@ -216,27 +216,27 @@ public class ChartView extends View {
|
|||||||
new ChartValueSeries(context,
|
new ChartValueSeries(context,
|
||||||
R.color.speed_fill,
|
R.color.speed_fill,
|
||||||
R.color.speed_border,
|
R.color.speed_border,
|
||||||
new ZoomSettings(MAX_INTERVALS, 0, Integer.MIN_VALUE,
|
new YAxisDimension(MAX_INTERVALS, 0, Integer.MAX_VALUE,
|
||||||
new int[] {1, 5, 10, 20, 50}),
|
new int[] {1, 5, 10, 20, 50}),
|
||||||
R.string.stats_speed);
|
R.string.stats_speed);
|
||||||
series[POWER_SERIES] =
|
series[POWER_SERIES] =
|
||||||
new ChartValueSeries(context,
|
new ChartValueSeries(context,
|
||||||
R.color.power_fill,
|
R.color.power_fill,
|
||||||
R.color.power_border,
|
R.color.power_border,
|
||||||
new ZoomSettings(MAX_INTERVALS, 0, 1000, new int[] {5, 50, 100, 200}),
|
new YAxisDimension(MAX_INTERVALS, 0, 1000, new int[] {5, 50, 100, 200}),
|
||||||
R.string.sensor_state_power);
|
R.string.sensor_state_power);
|
||||||
series[CADENCE_SERIES] =
|
series[CADENCE_SERIES] =
|
||||||
new ChartValueSeries(context,
|
new ChartValueSeries(context,
|
||||||
R.color.cadence_fill,
|
R.color.cadence_fill,
|
||||||
R.color.cadence_border,
|
R.color.cadence_border,
|
||||||
new ZoomSettings(MAX_INTERVALS, 0, Integer.MIN_VALUE,
|
new YAxisDimension(MAX_INTERVALS, 0, Integer.MAX_VALUE,
|
||||||
new int[] {5, 10, 25, 50}),
|
new int[] {5, 10, 25, 50}),
|
||||||
R.string.sensor_state_cadence);
|
R.string.sensor_state_cadence);
|
||||||
series[HEART_RATE_SERIES] =
|
series[HEART_RATE_SERIES] =
|
||||||
new ChartValueSeries(context,
|
new ChartValueSeries(context,
|
||||||
R.color.heartrate_fill,
|
R.color.heartrate_fill,
|
||||||
R.color.heartrate_border,
|
R.color.heartrate_border,
|
||||||
new ZoomSettings(MAX_INTERVALS, 0, Integer.MIN_VALUE,
|
new YAxisDimension(MAX_INTERVALS, 0, Integer.MAX_VALUE,
|
||||||
new int[] {25, 50}),
|
new int[] {25, 50}),
|
||||||
R.string.sensor_state_heart_rate);
|
R.string.sensor_state_heart_rate);
|
||||||
}
|
}
|
||||||
@@ -819,7 +819,7 @@ public class ChartView extends View {
|
|||||||
desiredY = topBorder + effectiveHeight + FONT_HEIGHT / 2 - desiredY - 1;
|
desiredY = topBorder + effectiveHeight + FONT_HEIGHT / 2 - desiredY - 1;
|
||||||
Paint p = new Paint(cvs.getLabelPaint());
|
Paint p = new Paint(cvs.getLabelPaint());
|
||||||
p.setTextAlign(Align.RIGHT);
|
p.setTextAlign(Align.RIGHT);
|
||||||
String text = cvs.getFormat().format(y);
|
String text = cvs.getNumberFormat().format(y);
|
||||||
c.drawText(text, x, desiredY, p);
|
c.drawText(text, x, desiredY, p);
|
||||||
return p.measureText(text);
|
return p.measureText(text);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,36 +15,33 @@
|
|||||||
*/
|
*/
|
||||||
package com.google.android.apps.mytracks;
|
package com.google.android.apps.mytracks;
|
||||||
|
|
||||||
import com.google.android.apps.mytracks.ChartValueSeries.ZoomSettings;
|
import com.google.android.apps.mytracks.ChartValueSeries.YAxisDimension;
|
||||||
import com.google.android.maps.mytracks.R;
|
import com.google.android.maps.mytracks.R;
|
||||||
|
|
||||||
import android.graphics.Paint.Style;
|
|
||||||
import android.test.AndroidTestCase;
|
import android.test.AndroidTestCase;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Tests {@link ChartValueSeries}.
|
||||||
|
*
|
||||||
* @author Sandor Dornbush
|
* @author Sandor Dornbush
|
||||||
*/
|
*/
|
||||||
public class ChartValueSeriesTest extends AndroidTestCase {
|
public class ChartValueSeriesTest extends AndroidTestCase {
|
||||||
private ChartValueSeries series;
|
private ChartValueSeries series;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setUp() throws Exception {
|
protected void setUp() throws Exception {
|
||||||
series = new ChartValueSeries(getContext(),
|
YAxisDimension yAxisDimension = new YAxisDimension(
|
||||||
R.color.elevation_fill,
|
5, Integer.MIN_VALUE, Integer.MAX_VALUE, new int[] { 100 });
|
||||||
R.color.elevation_border,
|
series = new ChartValueSeries(getContext(), R.color.elevation_fill, R.color.elevation_border,
|
||||||
new ZoomSettings(5, new int[] {100}),
|
yAxisDimension, R.string.stats_elevation);
|
||||||
R.string.stats_elevation);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testInitialConditions() {
|
public void testInitialConditions() {
|
||||||
assertEquals(0, series.getInterval());
|
assertEquals(1, series.getInterval());
|
||||||
assertEquals(1, series.getMaxLabelLength());
|
assertEquals(1, series.getMaxLabelLength());
|
||||||
assertEquals(0, series.getMin());
|
assertEquals(0, series.getMin());
|
||||||
assertEquals(0, series.getMax());
|
assertEquals(1, series.getMax());
|
||||||
assertEquals(0.0, series.getSpread());
|
assertEquals(getContext().getString(R.string.stats_elevation), series.getTitle());
|
||||||
assertEquals(Style.STROKE, series.getPaint().getStyle());
|
|
||||||
assertEquals(getContext().getString(R.string.stats_elevation),
|
|
||||||
series.getTitle());
|
|
||||||
assertTrue(series.isEnabled());
|
assertTrue(series.isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +49,7 @@ public class ChartValueSeriesTest extends AndroidTestCase {
|
|||||||
series.setEnabled(false);
|
series.setEnabled(false);
|
||||||
assertFalse(series.isEnabled());
|
assertFalse(series.isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testSmallUpdates() {
|
public void testSmallUpdates() {
|
||||||
series.update(0);
|
series.update(0);
|
||||||
series.update(10);
|
series.update(10);
|
||||||
@@ -61,7 +58,6 @@ public class ChartValueSeriesTest extends AndroidTestCase {
|
|||||||
assertEquals(3, series.getMaxLabelLength());
|
assertEquals(3, series.getMaxLabelLength());
|
||||||
assertEquals(0, series.getMin());
|
assertEquals(0, series.getMin());
|
||||||
assertEquals(100, series.getMax());
|
assertEquals(100, series.getMax());
|
||||||
assertEquals(100.0, series.getSpread());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBigUpdates() {
|
public void testBigUpdates() {
|
||||||
@@ -72,7 +68,6 @@ public class ChartValueSeriesTest extends AndroidTestCase {
|
|||||||
assertEquals(5, series.getMaxLabelLength());
|
assertEquals(5, series.getMaxLabelLength());
|
||||||
assertEquals(0, series.getMin());
|
assertEquals(0, series.getMin());
|
||||||
assertEquals(1000, series.getMax());
|
assertEquals(1000, series.getMax());
|
||||||
assertEquals(1000.0, series.getSpread());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testNotZeroBasedUpdates() {
|
public void testNotZeroBasedUpdates() {
|
||||||
@@ -83,56 +78,26 @@ public class ChartValueSeriesTest extends AndroidTestCase {
|
|||||||
assertEquals(5, series.getMaxLabelLength());
|
assertEquals(5, series.getMaxLabelLength());
|
||||||
assertEquals(500, series.getMin());
|
assertEquals(500, series.getMin());
|
||||||
assertEquals(1500, series.getMax());
|
assertEquals(1500, series.getMax());
|
||||||
assertEquals(1000.0, series.getSpread());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testZoomSettings_invalidArgs() {
|
public void testYAxisDimension_minAligned() {
|
||||||
try {
|
YAxisDimension yAxisDimension = new YAxisDimension(
|
||||||
new ZoomSettings(0, new int[] {10, 50, 100});
|
5, Integer.MIN_VALUE, Integer.MAX_VALUE, new int[] { 10, 50, 100 });
|
||||||
fail("Expected IllegalArgumentException");
|
assertEquals(10, yAxisDimension.getYAxisDimension(0, 15)[0]);
|
||||||
} catch (IllegalArgumentException e) {
|
assertEquals(10, yAxisDimension.getYAxisDimension(0, 50)[0]);
|
||||||
// OK.
|
assertEquals(50, yAxisDimension.getYAxisDimension(0, 111)[0]);
|
||||||
}
|
assertEquals(50, yAxisDimension.getYAxisDimension(0, 250)[0]);
|
||||||
try {
|
assertEquals(100, yAxisDimension.getYAxisDimension(0, 251)[0]);
|
||||||
new ZoomSettings(1, null);
|
assertEquals(100, yAxisDimension.getYAxisDimension(0, 10000)[0]);
|
||||||
fail("Expected IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// OK.
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
new ZoomSettings(1, new int[] {});
|
|
||||||
fail("Expected IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// OK.
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
new ZoomSettings(1, new int[] {1, 3, 2});
|
|
||||||
fail("Expected IllegalArgumentException");
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
// OK.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testZoomSettings_minAligned() {
|
|
||||||
ZoomSettings settings = new ZoomSettings(5, new int[] {10, 50, 100});
|
|
||||||
assertEquals(10, settings.calculateInterval(0, 15));
|
|
||||||
assertEquals(10, settings.calculateInterval(0, 50));
|
|
||||||
assertEquals(50, settings.calculateInterval(0, 111));
|
|
||||||
assertEquals(50, settings.calculateInterval(0, 250));
|
|
||||||
assertEquals(100, settings.calculateInterval(0, 251));
|
|
||||||
assertEquals(100, settings.calculateInterval(0, 10000));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testZoomSettings_minNotAligned() {
|
public void testYAxisDimension_minNotAligned() {
|
||||||
ZoomSettings settings = new ZoomSettings(5, new int[] {10, 50, 100});
|
YAxisDimension settings = new YAxisDimension(
|
||||||
assertEquals(50, settings.calculateInterval(5, 55));
|
5, Integer.MIN_VALUE, Integer.MAX_VALUE, new int[] { 10, 50, 100 });
|
||||||
assertEquals(10, settings.calculateInterval(10, 60));
|
assertEquals(50, settings.getYAxisDimension(5, 55)[0]);
|
||||||
assertEquals(50, settings.calculateInterval(7, 250));
|
assertEquals(10, settings.getYAxisDimension(10, 60)[0]);
|
||||||
assertEquals(100, settings.calculateInterval(7, 257));
|
assertEquals(50, settings.getYAxisDimension(7, 250)[0]);
|
||||||
assertEquals(100, settings.calculateInterval(11, 10000));
|
assertEquals(100, settings.getYAxisDimension(7, 257)[0]);
|
||||||
|
assertEquals(100, settings.getYAxisDimension(11, 10000)[0]);
|
||||||
// A regression test.
|
|
||||||
settings = new ZoomSettings(5, new int[] {5, 10, 20});
|
|
||||||
assertEquals(10, settings.calculateInterval(-37.14, -11.89));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user