mirror of
https://codeberg.org/OpenTracksApp/OpenTracks.git
synced 2026-10-02 09:33:06 +02:00
Clean up ChartValueSeries.
- include metric and imperial title id - include both speed and pace series
This commit is contained in:
@@ -33,6 +33,10 @@ limitations under the License.
|
||||
<color name="speed_border">#FF0066FF</color>
|
||||
<color name="speed_fill">#40C8E0FF</color>
|
||||
|
||||
<!-- Blue and a transparent blue -->
|
||||
<color name="pace_border">#FF0066FF</color>
|
||||
<color name="pace_fill">#40C8E0FF</color>
|
||||
|
||||
<!-- Red and a transparent red -->
|
||||
<color name="heartrate_border">#FFCC3300</color>
|
||||
<color name="heartrate_fill">#40E88A70</color>
|
||||
|
||||
@@ -451,6 +451,10 @@ limitations under the License.
|
||||
%2$.1f speed in miles per hour">
|
||||
Average speed: %1$.2f km/h (%2$.1f mi/h)
|
||||
</string>
|
||||
<string name="description_elevation_imperial"
|
||||
translation_description="Elevation in imperial units, feet.">
|
||||
Elevation (ft)
|
||||
</string>
|
||||
<string name="description_elevation_gain"
|
||||
translation_description="Elevation gain description.
|
||||
|
||||
@@ -458,6 +462,10 @@ limitations under the License.
|
||||
%2$d elevation in feet">
|
||||
Elevation gain: %1$d m (%2$d ft)
|
||||
</string>
|
||||
<string name="description_elevation_metric"
|
||||
translation_description="Elevation in metric units, meters.">
|
||||
Elevation (m)
|
||||
</string>
|
||||
<string name="description_fastest_pace"
|
||||
translation_description="Fastest pace description.
|
||||
|
||||
@@ -532,6 +540,14 @@ limitations under the License.
|
||||
%1$s time. E.g., '1:08:59'">
|
||||
Moving time: %1$s
|
||||
</string>
|
||||
<string name="description_pace_imperial"
|
||||
translation_description="Pace in imperial units, hours per mile.">
|
||||
Pace (hr/mi)
|
||||
</string>
|
||||
<string name="description_pace_metric"
|
||||
translation_description="Pace in metric units, hours per kilometer.">
|
||||
Pace (hr/km)
|
||||
</string>
|
||||
<string name="description_recorded_time"
|
||||
translation_description="Recorded time description.
|
||||
|
||||
@@ -554,6 +570,14 @@ limitations under the License.
|
||||
translation_description="Label for power with its unit watt (W).">
|
||||
Power (W)
|
||||
</string>
|
||||
<string name="description_speed_imperial"
|
||||
translation_description="Speed in imperial units, miles per hour.">
|
||||
Speed (mi/hr)
|
||||
</string>
|
||||
<string name="description_speed_metric"
|
||||
translation_description="Speed in metric units, kilometers per hour.">
|
||||
Speed (km/hr)
|
||||
</string>
|
||||
<string name="description_track_point"
|
||||
translation_description="Label for a track point">
|
||||
Point
|
||||
@@ -1898,26 +1922,6 @@ limitations under the License.
|
||||
of inclination to the horizontal, also known as slope or incline.">
|
||||
Grade
|
||||
</string>
|
||||
<string name="settings_stats_rate_pace_imperial"
|
||||
translation_description="In the 'Stats' settings, the option to display pace, with example in
|
||||
imperial units.">
|
||||
Pace (hr/mi)
|
||||
</string>
|
||||
<string name="settings_stats_rate_pace_metric"
|
||||
translation_description="In the 'Stats' settings, the option to display pace, with example in
|
||||
metric units.">
|
||||
Pace (hr/km)
|
||||
</string>
|
||||
<string name="settings_stats_rate_speed_imperial"
|
||||
translation_description="In the 'Stats' settings, the option to display speed, with example in
|
||||
imperial units.">
|
||||
Speed (mi/hr)
|
||||
</string>
|
||||
<string name="settings_stats_rate_speed_metric"
|
||||
translation_description="In the 'Stats' settings, the option to display speed, with example in
|
||||
metric units.">
|
||||
Speed (km/hr)
|
||||
</string>
|
||||
<string name="settings_stats_rate_title"
|
||||
translation_description="In the 'Stats' settings, the option to change the preferred rate,
|
||||
either speed (mi/hr) or pace (hr/mi).">
|
||||
|
||||
@@ -22,195 +22,93 @@ import com.google.common.annotations.VisibleForTesting;
|
||||
import android.content.Context;
|
||||
import android.graphics.Canvas;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Path;
|
||||
|
||||
import java.text.NumberFormat;
|
||||
|
||||
/**
|
||||
* This class encapsulates the meta data for one series of chart values.
|
||||
*
|
||||
* This class encapsulates the meta data for one series of the chart values.
|
||||
*
|
||||
* @author Sandor Dornbush
|
||||
*/
|
||||
public class ChartValueSeries {
|
||||
|
||||
private static final float STROKE_WIDTH = 2f;
|
||||
|
||||
private final int absoluteMin;
|
||||
private final int absoluteMax;
|
||||
private final int[] intervalValues;
|
||||
private final int metricTitleId;
|
||||
private final int imperialTitleId;
|
||||
private final Paint fillPaint;
|
||||
private final Paint strokePaint;
|
||||
private final Paint titlePaint;
|
||||
private final Paint markerPaint;
|
||||
private final ExtremityMonitor extremityMonitor;
|
||||
private final NumberFormat numberFormat;
|
||||
private final Path path;
|
||||
private final Paint fillPaint;
|
||||
private final Paint strokePaint;
|
||||
private final Paint labelPaint;
|
||||
private final YAxisDimension markingInterval;
|
||||
private String title;
|
||||
|
||||
private boolean enabled = true;
|
||||
|
||||
private int interval = 1;
|
||||
private int effectiveMin = 0;
|
||||
private int effectiveMax = 1;
|
||||
private int minMarkerValue = 0;
|
||||
private int maxMarkerValue = interval * ChartView.Y_AXIS_INTERVALS;
|
||||
private boolean enabled = true;
|
||||
|
||||
/**
|
||||
* This class to calculates the y axis dimension, interval, effective min, and
|
||||
* effective max.
|
||||
*/
|
||||
public static class YAxisDimension {
|
||||
private final int numberOfIntervals;
|
||||
private final int absoluteMin;
|
||||
private final int absoluteMax;
|
||||
private final int[] intervalValues;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param numberOfIntervals the number of intervals
|
||||
* @param absoluteMin the absolute minimum value
|
||||
* @param absoluteMax the absolute maximum value
|
||||
* @param intervalValues the list of interval values
|
||||
*/
|
||||
public YAxisDimension(
|
||||
int numberOfIntervals, int absoluteMin, int absoluteMax, int[] intervalValues) {
|
||||
this.numberOfIntervals = numberOfIntervals;
|
||||
this.absoluteMin = absoluteMin;
|
||||
this.absoluteMax = absoluteMax;
|
||||
this.intervalValues = intervalValues;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the y axis dimension. Returns an array of int[3], containing interval, effectiveMin,
|
||||
* and effectiveMax.
|
||||
*
|
||||
* @param min the min value
|
||||
* @param max the max value
|
||||
*/
|
||||
public int[] getYAxisDimension(double min, double max) {
|
||||
min = Math.max(min, absoluteMin);
|
||||
max = Math.min(max, absoluteMax);
|
||||
int interval = 0;
|
||||
int effectiveMin = 0;
|
||||
for (int i = 0; i < intervalValues.length; i++) {
|
||||
interval = intervalValues[i];
|
||||
effectiveMin = getEffetiveMin(min, interval);
|
||||
double targetInterval = (max - effectiveMin) / numberOfIntervals;
|
||||
if (interval >= targetInterval) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
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.
|
||||
*
|
||||
* Constructor.
|
||||
*
|
||||
* @param context the context
|
||||
* @param absoluteMin the absolute min value
|
||||
* @param absoluteMax the absolute max value
|
||||
* @param intervalValues the list of interval values
|
||||
* @param metricTitleId the metric title id
|
||||
* @param imperialTitleId the imperial title id
|
||||
* @param fillColor the fill color
|
||||
* @param strokeColor the stroke color
|
||||
* @param yAxisDimension the marking interval
|
||||
* @param titleId the title id
|
||||
*/
|
||||
public ChartValueSeries(Context context, int fillColor, int strokeColor,
|
||||
YAxisDimension yAxisDimension, int titleId) {
|
||||
extremityMonitor = new ExtremityMonitor();
|
||||
numberFormat = NumberFormat.getIntegerInstance();
|
||||
path = new Path();
|
||||
public ChartValueSeries(Context context, int absoluteMin, int absoluteMax, int[] intervalValues,
|
||||
int metricTitleId, int imperialTitleId, int fillColor, int strokeColor) {
|
||||
this.absoluteMin = absoluteMin;
|
||||
this.absoluteMax = absoluteMax;
|
||||
this.intervalValues = intervalValues;
|
||||
this.metricTitleId = metricTitleId;
|
||||
this.imperialTitleId = imperialTitleId;
|
||||
|
||||
fillPaint = new Paint();
|
||||
fillPaint.setStyle(Style.FILL);
|
||||
fillPaint.setColor(context.getResources().getColor(fillColor));
|
||||
fillPaint.setAntiAlias(true);
|
||||
if (strokeColor != -1) {
|
||||
strokePaint = new Paint();
|
||||
strokePaint.setStyle(Style.STROKE);
|
||||
strokePaint.setColor(context.getResources().getColor(strokeColor));
|
||||
strokePaint.setAntiAlias(true);
|
||||
// Make a copy of the stroke paint with the default thickness
|
||||
labelPaint = new Paint(strokePaint);
|
||||
strokePaint.setStrokeWidth(STROKE_WIDTH);
|
||||
} else {
|
||||
strokePaint = null;
|
||||
labelPaint = fillPaint;
|
||||
}
|
||||
this.markingInterval = yAxisDimension;
|
||||
title = context.getString(titleId);
|
||||
|
||||
strokePaint = new Paint();
|
||||
strokePaint.setStyle(Style.STROKE);
|
||||
strokePaint.setColor(context.getResources().getColor(strokeColor));
|
||||
strokePaint.setAntiAlias(true);
|
||||
|
||||
// Make copies of the stroke paint with the default thickness
|
||||
titlePaint = new Paint(strokePaint);
|
||||
titlePaint.setTextSize(ChartView.LARGE_TEXT_SIZE);
|
||||
titlePaint.setTextAlign(Align.CENTER);
|
||||
|
||||
markerPaint = new Paint(strokePaint);
|
||||
markerPaint.setTextSize(ChartView.MEDIUM_TEXT_SIZE);
|
||||
markerPaint.setTextAlign(Align.RIGHT);
|
||||
|
||||
// Set stroke paint thickness
|
||||
strokePaint.setStrokeWidth(STROKE_WIDTH);
|
||||
|
||||
extremityMonitor = new ExtremityMonitor();
|
||||
numberFormat = NumberFormat.getIntegerInstance();
|
||||
path = new Path();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the series has data.
|
||||
* Sets the series enabled value.
|
||||
*
|
||||
* @param enabled true to enable
|
||||
*/
|
||||
public boolean hasData() {
|
||||
return extremityMonitor.hasData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the series with a new value.
|
||||
*
|
||||
* @param value the new value
|
||||
*/
|
||||
public void update(double value) {
|
||||
extremityMonitor.update(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number format for the series.
|
||||
*/
|
||||
public NumberFormat getNumberFormat() {
|
||||
return numberFormat;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path.
|
||||
*/
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the label paint.
|
||||
*/
|
||||
public Paint getLabelPaint() {
|
||||
return labelPaint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title.
|
||||
*/
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the title.
|
||||
*
|
||||
* @param title the title
|
||||
*/
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,65 +119,144 @@ public class ChartValueSeries {
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the enabled value.
|
||||
*
|
||||
* @param enabled true to enable
|
||||
* Returns true if the series has data.
|
||||
*/
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
public boolean hasData() {
|
||||
return extremityMonitor.hasData();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Updates the series with a new value.
|
||||
*
|
||||
* @param value the new value
|
||||
*/
|
||||
public void update(double value) {
|
||||
extremityMonitor.update(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the path.
|
||||
*/
|
||||
public Path getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
canvas.drawPath(path, strokePaint);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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];
|
||||
double min = hasData() ? extremityMonitor.getMin() : 0.0;
|
||||
double max = hasData() ? extremityMonitor.getMax() : 1.0;
|
||||
min = Math.max(min, absoluteMin);
|
||||
max = Math.min(max, absoluteMax);
|
||||
interval = getInterval(min, max);
|
||||
minMarkerValue = getMinMarkerValue(min, interval);
|
||||
maxMarkerValue = minMarkerValue + interval * ChartView.Y_AXIS_INTERVALS;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the y axis interval value.
|
||||
* Gets the interval value.
|
||||
*
|
||||
* @param min the min value
|
||||
* @param max the max value
|
||||
*/
|
||||
private int getInterval(double min, double max) {
|
||||
for (int i = 0; i < intervalValues.length; i++) {
|
||||
int intervalValue = intervalValues[i];
|
||||
int minValue = getMinMarkerValue(min, intervalValue);
|
||||
double targetInterval = (max - minValue) / ChartView.Y_AXIS_INTERVALS;
|
||||
if (intervalValue >= targetInterval) {
|
||||
return intervalValue;
|
||||
}
|
||||
}
|
||||
// Return the largest interval
|
||||
return intervalValues[intervalValues.length - 1];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the min marker value.
|
||||
*
|
||||
* @param min the min series value
|
||||
* @param intervalValue the interval value
|
||||
*/
|
||||
private int getMinMarkerValue(double min, int intervalValue) {
|
||||
// Round down to the nearest intervalValue
|
||||
int value = ((int) (min / intervalValue)) * intervalValue;
|
||||
// value > min if min is negative
|
||||
if (value > min) {
|
||||
return value - intervalValue;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the interval value.
|
||||
*/
|
||||
public int getInterval() {
|
||||
return interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the minimum value.
|
||||
* Gets the minimum marker value.
|
||||
*/
|
||||
public int getMin() {
|
||||
return effectiveMin;
|
||||
public int getMinMarkerValue() {
|
||||
return minMarkerValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum value.
|
||||
* Gets the maximum marker value.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
int getMax() {
|
||||
return effectiveMax;
|
||||
int getMaxMarkerValue() {
|
||||
return maxMarkerValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the maximum label length.
|
||||
* Gets the title id.
|
||||
*/
|
||||
public int getMaxLabelLength() {
|
||||
return Math.max(numberFormat.format(getMin()).length(), numberFormat.format(getMax()).length());
|
||||
public int getTitleId(boolean metricUnits) {
|
||||
return metricUnits ? metricTitleId : imperialTitleId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the title paint.
|
||||
*/
|
||||
public Paint getTitlePaint() {
|
||||
return titlePaint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the marker paint.
|
||||
*/
|
||||
public Paint getMarkerPaint() {
|
||||
return markerPaint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the largest marker.
|
||||
*/
|
||||
public String getLargestMarker() {
|
||||
String minMarker = numberFormat.format(getMinMarkerValue());
|
||||
String maxMarker = numberFormat.format(getMaxMarkerValue());
|
||||
return minMarker.length() >= maxMarker.length() ? minMarker : maxMarker;
|
||||
}
|
||||
|
||||
/**
|
||||
* Formats a marker value.
|
||||
*
|
||||
* @param value the value
|
||||
*/
|
||||
public String formatMarker(int value) {
|
||||
return numberFormat.format(value);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.ChartValueSeries.YAxisDimension;
|
||||
import com.google.android.apps.mytracks.content.Waypoint;
|
||||
import com.google.android.apps.mytracks.stats.ExtremityMonitor;
|
||||
import com.google.android.apps.mytracks.util.IntentUtils;
|
||||
@@ -30,7 +29,6 @@ import android.graphics.Canvas;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.DashPathEffect;
|
||||
import android.graphics.Paint;
|
||||
import android.graphics.Paint.Align;
|
||||
import android.graphics.Paint.Style;
|
||||
import android.graphics.Path;
|
||||
import android.graphics.drawable.Drawable;
|
||||
@@ -50,6 +48,21 @@ import java.util.ArrayList;
|
||||
* @author Leif Hendrik Wilden
|
||||
*/
|
||||
public class ChartView extends View {
|
||||
|
||||
public static final float LARGE_TEXT_SIZE = 22f;
|
||||
public static final float MEDIUM_TEXT_SIZE = 18f;
|
||||
public static final float SMALL_TEXT_SIZE = 14f;
|
||||
|
||||
public static final int Y_AXIS_INTERVALS = 5;
|
||||
|
||||
public static final int NUM_SERIES = 6;
|
||||
public static final int ELEVATION_SERIES = 0;
|
||||
public static final int SPEED_SERIES = 1;
|
||||
public static final int PACE_SERIES = 2;
|
||||
public static final int HEART_RATE_SERIES = 3;
|
||||
public static final int CADENCE_SERIES = 4;
|
||||
public static final int POWER_SERIES = 5;
|
||||
|
||||
private static final int MIN_ZOOM_LEVEL = 1;
|
||||
|
||||
/*
|
||||
@@ -66,8 +79,6 @@ public class ChartView extends View {
|
||||
private int zoomLevel = 1;
|
||||
private int maxZoomLevel = 10;
|
||||
|
||||
private static final int MAX_INTERVALS = 5;
|
||||
|
||||
/*
|
||||
* Borders, margins, dimensions (in pixels):
|
||||
*/
|
||||
@@ -109,15 +120,6 @@ public class ChartView extends View {
|
||||
*/
|
||||
private double maxX = 1;
|
||||
|
||||
/**
|
||||
* The various series.
|
||||
*/
|
||||
public static final int ELEVATION_SERIES = 0;
|
||||
public static final int SPEED_SERIES = 1;
|
||||
public static final int POWER_SERIES = 2;
|
||||
public static final int CADENCE_SERIES = 3;
|
||||
public static final int HEART_RATE_SERIES = 4;
|
||||
public static final int NUM_SERIES = 5;
|
||||
private ChartValueSeries[] series;
|
||||
|
||||
private final ExtremityMonitor xMonitor = new ExtremityMonitor();
|
||||
@@ -204,41 +206,54 @@ public class ChartView extends View {
|
||||
series = new ChartValueSeries[NUM_SERIES];
|
||||
|
||||
// Create the value series.
|
||||
series[ELEVATION_SERIES] =
|
||||
new ChartValueSeries(context,
|
||||
R.color.elevation_fill,
|
||||
R.color.elevation_border,
|
||||
new YAxisDimension(MAX_INTERVALS, Integer.MIN_VALUE, Integer.MAX_VALUE,
|
||||
new int[] {5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000}),
|
||||
R.string.stats_elevation);
|
||||
|
||||
series[SPEED_SERIES] =
|
||||
new ChartValueSeries(context,
|
||||
R.color.speed_fill,
|
||||
R.color.speed_border,
|
||||
new YAxisDimension(MAX_INTERVALS, 0, Integer.MAX_VALUE,
|
||||
new int[] {1, 5, 10, 20, 50}),
|
||||
R.string.stats_speed);
|
||||
series[POWER_SERIES] =
|
||||
new ChartValueSeries(context,
|
||||
R.color.power_fill,
|
||||
R.color.power_border,
|
||||
new YAxisDimension(MAX_INTERVALS, 0, 1000, new int[] {5, 50, 100, 200}),
|
||||
R.string.sensor_state_power);
|
||||
series[CADENCE_SERIES] =
|
||||
new ChartValueSeries(context,
|
||||
R.color.cadence_fill,
|
||||
R.color.cadence_border,
|
||||
new YAxisDimension(MAX_INTERVALS, 0, Integer.MAX_VALUE,
|
||||
new int[] {5, 10, 25, 50}),
|
||||
R.string.sensor_state_cadence);
|
||||
series[HEART_RATE_SERIES] =
|
||||
new ChartValueSeries(context,
|
||||
R.color.heartrate_fill,
|
||||
R.color.heartrate_border,
|
||||
new YAxisDimension(MAX_INTERVALS, 0, Integer.MAX_VALUE,
|
||||
new int[] {25, 50}),
|
||||
R.string.sensor_state_heart_rate);
|
||||
series[ELEVATION_SERIES] = new ChartValueSeries(context,
|
||||
Integer.MIN_VALUE,
|
||||
Integer.MAX_VALUE,
|
||||
new int[] {5, 10, 25, 50, 100, 250, 500, 1000, 2500, 5000},
|
||||
R.string.description_elevation_metric,
|
||||
R.string.description_elevation_imperial,
|
||||
R.color.elevation_fill,
|
||||
R.color.elevation_border);
|
||||
series[SPEED_SERIES] = new ChartValueSeries(context,
|
||||
0,
|
||||
Integer.MAX_VALUE,
|
||||
new int[] {1, 5, 10, 20, 50},
|
||||
R.string.description_speed_metric,
|
||||
R.string.description_speed_imperial,
|
||||
R.color.speed_fill,
|
||||
R.color.speed_border);
|
||||
series[PACE_SERIES] = new ChartValueSeries(context,
|
||||
0,
|
||||
Integer.MAX_VALUE,
|
||||
new int[] { 1, 2, 5, 10, 15, 20, 30, 60, 120 },
|
||||
R.string.description_pace_metric,
|
||||
R.string.description_pace_imperial,
|
||||
R.color.pace_fill,
|
||||
R.color.pace_border);
|
||||
series[HEART_RATE_SERIES] = new ChartValueSeries(context,
|
||||
0,
|
||||
Integer.MAX_VALUE,
|
||||
new int[] {25, 50},
|
||||
R.string.description_sensor_heart_rate,
|
||||
R.string.description_sensor_heart_rate,
|
||||
R.color.heartrate_fill,
|
||||
R.color.heartrate_border);
|
||||
series[CADENCE_SERIES] = new ChartValueSeries(context,
|
||||
0,
|
||||
Integer.MAX_VALUE,
|
||||
new int[] {5, 10, 25, 50},
|
||||
R.string.description_sensor_cadence,
|
||||
R.string.description_sensor_cadence,
|
||||
R.color.cadence_fill,
|
||||
R.color.cadence_border);
|
||||
series[POWER_SERIES] = new ChartValueSeries(context,
|
||||
0,
|
||||
1000,
|
||||
new int[] {5, 50, 100, 200},
|
||||
R.string.description_sensor_power,
|
||||
R.string.description_sensor_power,
|
||||
R.color.power_fill,
|
||||
R.color.power_border);
|
||||
}
|
||||
|
||||
public void clearWaypoints() {
|
||||
@@ -263,12 +278,6 @@ public class ChartView extends View {
|
||||
this.metricUnits = metricUnits;
|
||||
}
|
||||
|
||||
public void setReportSpeed(boolean reportSpeed, Context c) {
|
||||
series[SPEED_SERIES].setTitle(c.getString(reportSpeed
|
||||
? R.string.stats_speed
|
||||
: R.string.stats_pace));
|
||||
}
|
||||
|
||||
private void addDataPointInternal(double[] theData) {
|
||||
xMonitor.update(theData[0]);
|
||||
int min = Math.min(series.length, theData.length - 1);
|
||||
@@ -622,7 +631,8 @@ public class ChartView extends View {
|
||||
for (ChartValueSeries cvs : series) {
|
||||
if (cvs.isEnabled() && cvs.hasData()) {
|
||||
int x = (int) (w * (double) ++j / sections) + getScrollX();
|
||||
c.drawText(cvs.getTitle(), x, topBorder, cvs.getLabelPaint());
|
||||
c.drawText(
|
||||
getContext().getString(cvs.getTitleId(metricUnits)), x, topBorder, cvs.getTitlePaint());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -719,7 +729,7 @@ public class ChartView extends View {
|
||||
int maxLength = 0;
|
||||
for (ChartValueSeries cvs : series) {
|
||||
if (cvs.isEnabled() && cvs.hasData()) {
|
||||
maxLength += cvs.getMaxLabelLength();
|
||||
maxLength += cvs.getLargestMarker().length();
|
||||
}
|
||||
}
|
||||
float density = getContext().getResources().getDisplayMetrics().density;
|
||||
@@ -758,9 +768,9 @@ public class ChartView extends View {
|
||||
}
|
||||
|
||||
private int getY(ChartValueSeries cvs, double y) {
|
||||
int effectiveSpread = cvs.getInterval() * MAX_INTERVALS;
|
||||
int effectiveSpread = cvs.getInterval() * Y_AXIS_INTERVALS;
|
||||
return topBorder + effectiveHeight
|
||||
- (int) ((y - cvs.getMin()) * effectiveHeight / effectiveSpread);
|
||||
- (int) ((y - cvs.getMinMarkerValue()) * effectiveHeight / effectiveSpread);
|
||||
}
|
||||
|
||||
/** Draws the labels on the X axis into the given canvas. */
|
||||
@@ -792,8 +802,8 @@ public class ChartView extends View {
|
||||
private float drawYLabels(ChartValueSeries cvs, Canvas c, int x) {
|
||||
int interval = cvs.getInterval();
|
||||
float maxTextWidth = 0;
|
||||
for (int i = 0; i < MAX_INTERVALS; ++i) {
|
||||
maxTextWidth = Math.max(maxTextWidth, drawYLabel(cvs, c, x, i * interval + cvs.getMin()));
|
||||
for (int i = 0; i < Y_AXIS_INTERVALS; ++i) {
|
||||
maxTextWidth = Math.max(maxTextWidth, drawYLabel(cvs, c, x, i * interval + cvs.getMinMarkerValue()));
|
||||
}
|
||||
return maxTextWidth;
|
||||
}
|
||||
@@ -814,14 +824,13 @@ public class ChartView extends View {
|
||||
|
||||
/** Draws a single label on the Y axis. */
|
||||
private float drawYLabel(ChartValueSeries cvs, Canvas c, int x, int y) {
|
||||
int desiredY = (int) ((y - cvs.getMin()) * effectiveHeight /
|
||||
(cvs.getInterval() * MAX_INTERVALS));
|
||||
int desiredY = (int) ((y - cvs.getMinMarkerValue()) * effectiveHeight /
|
||||
(cvs.getInterval() * Y_AXIS_INTERVALS));
|
||||
desiredY = topBorder + effectiveHeight + FONT_HEIGHT / 2 - desiredY - 1;
|
||||
Paint p = new Paint(cvs.getLabelPaint());
|
||||
p.setTextAlign(Align.RIGHT);
|
||||
String text = cvs.getNumberFormat().format(y);
|
||||
c.drawText(text, x, desiredY, p);
|
||||
return p.measureText(text);
|
||||
Paint markerPaint = cvs.getMarkerPaint();
|
||||
String text = cvs.formatMarker(y);
|
||||
c.drawText(text, x, desiredY, markerPaint);
|
||||
return markerPaint.measureText(text);
|
||||
}
|
||||
|
||||
/** Draws the actual X axis line and its label. */
|
||||
@@ -844,8 +853,8 @@ public class ChartView extends View {
|
||||
canvas.drawLine(leftBorder, UNIT_BORDER + topBorder,
|
||||
leftBorder, effectiveHeight + topBorder,
|
||||
borderPaint);
|
||||
for (int i = 1; i < MAX_INTERVALS; ++i) {
|
||||
int y = i * effectiveHeight / MAX_INTERVALS + topBorder;
|
||||
for (int i = 1; i < Y_AXIS_INTERVALS; ++i) {
|
||||
int y = i * effectiveHeight / Y_AXIS_INTERVALS + topBorder;
|
||||
canvas.drawLine(leftBorder - 5, y, leftBorder, y, gridPaint);
|
||||
}
|
||||
|
||||
@@ -858,8 +867,8 @@ public class ChartView extends View {
|
||||
/** Draws the grid for the graph. */
|
||||
private void drawGrid(Canvas c) {
|
||||
float rightEdge = getX(maxX);
|
||||
for (int i = 1; i < MAX_INTERVALS; ++i) {
|
||||
int y = i * effectiveHeight / MAX_INTERVALS + topBorder;
|
||||
for (int i = 1; i < Y_AXIS_INTERVALS; ++i) {
|
||||
int y = i * effectiveHeight / Y_AXIS_INTERVALS + topBorder;
|
||||
c.drawLine(leftBorder, y, rightEdge, y, gridBarPaint);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -77,15 +77,15 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
private boolean reportSpeed = true;
|
||||
|
||||
private boolean chartByDistance = true;
|
||||
private boolean[] chartShow = new boolean[] {true, true, true, true, true};
|
||||
private boolean[] chartShow = new boolean[] {true, true, true, true, true, true};
|
||||
|
||||
// UI elements
|
||||
private ChartView chartView;
|
||||
private ZoomControls zoomControls;
|
||||
|
||||
/**
|
||||
* A runnable that will remove the spinner (if any), enable/disable zoom
|
||||
* controls and orange pointer as appropriate and redraw.
|
||||
* A runnable that will enable/disable zoom controls and orange pointer as
|
||||
* appropriate and redraw.
|
||||
*/
|
||||
private final Runnable updateChart = new Runnable() {
|
||||
@Override
|
||||
@@ -215,7 +215,7 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
@Override
|
||||
public void onNewTrackPoint(Location location) {
|
||||
if (LocationUtils.isValidLocation(location)) {
|
||||
double[] data = new double[6];
|
||||
double[] data = new double[ChartView.NUM_SERIES + 1];
|
||||
fillDataPoint(location, data);
|
||||
pendingPoints.add(data);
|
||||
}
|
||||
@@ -280,7 +280,8 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
return false;
|
||||
}
|
||||
reportSpeed = speed;
|
||||
chartView.setReportSpeed(speed, getActivity());
|
||||
setSeriesEnabled(ChartView.SPEED_SERIES, reportSpeed);
|
||||
setSeriesEnabled(ChartView.PACE_SERIES, !reportSpeed);
|
||||
getActivity().runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -310,6 +311,10 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
getActivity(), R.string.chart_show_speed_key, PreferencesUtils.CHART_SHOW_SPEED_DEFAULT))) {
|
||||
needUpdate = true;
|
||||
}
|
||||
if (setSeriesEnabled(ChartView.PACE_SERIES, !PreferencesUtils.getBoolean(
|
||||
getActivity(), R.string.chart_show_speed_key, PreferencesUtils.CHART_SHOW_SPEED_DEFAULT))) {
|
||||
needUpdate = true;
|
||||
}
|
||||
if (setSeriesEnabled(ChartView.POWER_SERIES, PreferencesUtils.getBoolean(
|
||||
getActivity(), R.string.chart_show_power_key, PreferencesUtils.CHART_SHOW_POWER_DEFAULT))) {
|
||||
needUpdate = true;
|
||||
@@ -405,13 +410,14 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a location, fill in a data point, an array of double[6]. <br>
|
||||
* Given a location, fill in a data point, an array of double[]. <br>
|
||||
* data[0] = time/distance <br>
|
||||
* data[1] = elevation <br>
|
||||
* data[2] = speed <br>
|
||||
* data[3] = power <br>
|
||||
* data[4] = cadence <br>
|
||||
* data[5] = heart rate <br>
|
||||
* data[3] = pace <br>
|
||||
* data[4] = heart rate <br>
|
||||
* data[5] = cadence <br>
|
||||
* data[6] = power <br>
|
||||
*
|
||||
* @param location the location
|
||||
* @param data the data point to fill in, can be null
|
||||
@@ -421,9 +427,10 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
double timeOrDistance = Double.NaN;
|
||||
double elevation = Double.NaN;
|
||||
double speed = Double.NaN;
|
||||
double power = Double.NaN;
|
||||
double pace = Double.NaN;
|
||||
double heartRate = Double.NaN;
|
||||
double cadence = Double.NaN;
|
||||
double heartRate = Double.NaN;
|
||||
double power = Double.NaN;
|
||||
|
||||
// TODO: Use TripStatisticsBuilder
|
||||
if (chartByDistance) {
|
||||
@@ -460,36 +467,36 @@ public class ChartFragment extends Fragment implements TrackDataListener {
|
||||
if (!metricUnits) {
|
||||
speed *= UnitConversions.KM_TO_MI;
|
||||
}
|
||||
if (!reportSpeed) {
|
||||
speed = speed == 0 ? 0.0 : 60.0 / speed;
|
||||
}
|
||||
|
||||
pace = speed == 0 ? 0.0 : 60.0 / speed;
|
||||
|
||||
if (location instanceof MyTracksLocation
|
||||
&& ((MyTracksLocation) location).getSensorDataSet() != null) {
|
||||
SensorDataSet sensorDataSet = ((MyTracksLocation) location).getSensorDataSet();
|
||||
if (sensorDataSet.hasPower() && sensorDataSet.getPower().getState() == Sensor.SensorState.SENDING
|
||||
&& sensorDataSet.getPower().hasValue()) {
|
||||
power = sensorDataSet.getPower().getValue();
|
||||
if (sensorDataSet.hasHeartRate()
|
||||
&& sensorDataSet.getHeartRate().getState() == Sensor.SensorState.SENDING
|
||||
&& sensorDataSet.getHeartRate().hasValue()) {
|
||||
heartRate = sensorDataSet.getHeartRate().getValue();
|
||||
}
|
||||
if (sensorDataSet.hasCadence()
|
||||
&& sensorDataSet.getCadence().getState() == Sensor.SensorState.SENDING
|
||||
&& sensorDataSet.getCadence().hasValue()) {
|
||||
cadence = sensorDataSet.getCadence().getValue();
|
||||
}
|
||||
if (sensorDataSet.hasHeartRate()
|
||||
&& sensorDataSet.getHeartRate().getState() == Sensor.SensorState.SENDING
|
||||
&& sensorDataSet.getHeartRate().hasValue()) {
|
||||
heartRate = sensorDataSet.getHeartRate().getValue();
|
||||
if (sensorDataSet.hasPower()
|
||||
&& sensorDataSet.getPower().getState() == Sensor.SensorState.SENDING
|
||||
&& sensorDataSet.getPower().hasValue()) {
|
||||
power = sensorDataSet.getPower().getValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (data != null) {
|
||||
data[0] = timeOrDistance;
|
||||
data[1] = elevation;
|
||||
data[2] = speed;
|
||||
data[3] = power;
|
||||
data[4] = cadence;
|
||||
data[5] = heartRate;
|
||||
data[3] = pace;
|
||||
data[4] = heartRate;
|
||||
data[5] = cadence;
|
||||
data[6] = power;
|
||||
}
|
||||
lastLocation = location;
|
||||
}
|
||||
|
||||
+2
-1
@@ -44,7 +44,8 @@ import android.widget.TextView;
|
||||
public class UploadResultActivity extends FragmentActivity {
|
||||
|
||||
private static final String TAG = UploadResultActivity.class.getSimpleName();
|
||||
private static final int DIALOG_RESULT_ID = 0;
|
||||
@VisibleForTesting
|
||||
static final int DIALOG_RESULT_ID = 0;
|
||||
|
||||
private SendRequest sendRequest;
|
||||
private String shareUrl;
|
||||
|
||||
@@ -71,11 +71,9 @@ public class StatsSettingsActivity extends AbstractSettingsActivity {
|
||||
getString(R.string.report_speed_key));
|
||||
boolean metric = PreferencesUtils.getBoolean(
|
||||
this, R.string.metric_units_key, PreferencesUtils.METRIC_UNITS_DEFAULT);
|
||||
reportSpeedCheckBoxPreference.setSummaryOn(
|
||||
metric ? getString(R.string.settings_stats_rate_speed_metric)
|
||||
: getString(R.string.settings_stats_rate_speed_imperial));
|
||||
reportSpeedCheckBoxPreference.setSummaryOff(
|
||||
metric ? getString(R.string.settings_stats_rate_pace_metric)
|
||||
: getString(R.string.settings_stats_rate_pace_imperial));
|
||||
reportSpeedCheckBoxPreference.setSummaryOn(metric ? getString(R.string.description_speed_metric)
|
||||
: getString(R.string.description_speed_imperial));
|
||||
reportSpeedCheckBoxPreference.setSummaryOff(metric ? getString(R.string.description_pace_metric)
|
||||
: getString(R.string.description_pace_imperial));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
*/
|
||||
package com.google.android.apps.mytracks;
|
||||
|
||||
import com.google.android.apps.mytracks.ChartValueSeries.YAxisDimension;
|
||||
import com.google.android.maps.mytracks.R;
|
||||
|
||||
import android.test.AndroidTestCase;
|
||||
@@ -30,18 +29,20 @@ public class ChartValueSeriesTest extends AndroidTestCase {
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
YAxisDimension yAxisDimension = new YAxisDimension(
|
||||
5, Integer.MIN_VALUE, Integer.MAX_VALUE, new int[] { 100 });
|
||||
series = new ChartValueSeries(getContext(), R.color.elevation_fill, R.color.elevation_border,
|
||||
yAxisDimension, R.string.stats_elevation);
|
||||
series = new ChartValueSeries(getContext(),
|
||||
Integer.MIN_VALUE,
|
||||
Integer.MAX_VALUE,
|
||||
new int[] {100, 1000 },
|
||||
R.string.description_elevation_metric,
|
||||
R.string.description_elevation_imperial,
|
||||
R.color.elevation_fill,
|
||||
R.color.elevation_border);
|
||||
}
|
||||
|
||||
public void testInitialConditions() {
|
||||
assertEquals(1, series.getInterval());
|
||||
assertEquals(1, series.getMaxLabelLength());
|
||||
assertEquals(0, series.getMin());
|
||||
assertEquals(1, series.getMax());
|
||||
assertEquals(getContext().getString(R.string.stats_elevation), series.getTitle());
|
||||
assertEquals(0, series.getMinMarkerValue());
|
||||
assertEquals(5, series.getMaxMarkerValue());
|
||||
assertTrue(series.isEnabled());
|
||||
}
|
||||
|
||||
@@ -55,49 +56,25 @@ public class ChartValueSeriesTest extends AndroidTestCase {
|
||||
series.update(10);
|
||||
series.updateDimension();
|
||||
assertEquals(100, series.getInterval());
|
||||
assertEquals(3, series.getMaxLabelLength());
|
||||
assertEquals(0, series.getMin());
|
||||
assertEquals(100, series.getMax());
|
||||
assertEquals(0, series.getMinMarkerValue());
|
||||
assertEquals(500, series.getMaxMarkerValue());
|
||||
}
|
||||
|
||||
public void testBigUpdates() {
|
||||
series.update(0);
|
||||
series.update(901);
|
||||
series.updateDimension();
|
||||
assertEquals(100, series.getInterval());
|
||||
assertEquals(5, series.getMaxLabelLength());
|
||||
assertEquals(0, series.getMin());
|
||||
assertEquals(1000, series.getMax());
|
||||
assertEquals(1000, series.getInterval());
|
||||
assertEquals(0, series.getMinMarkerValue());
|
||||
assertEquals(5000, series.getMaxMarkerValue());
|
||||
}
|
||||
|
||||
public void testNotZeroBasedUpdates() {
|
||||
series.update(500);
|
||||
series.update(1401);
|
||||
series.update(220);
|
||||
series.update(250);
|
||||
series.updateDimension();
|
||||
assertEquals(100, series.getInterval());
|
||||
assertEquals(5, series.getMaxLabelLength());
|
||||
assertEquals(500, series.getMin());
|
||||
assertEquals(1500, series.getMax());
|
||||
}
|
||||
|
||||
public void testYAxisDimension_minAligned() {
|
||||
YAxisDimension yAxisDimension = new YAxisDimension(
|
||||
5, Integer.MIN_VALUE, Integer.MAX_VALUE, new int[] { 10, 50, 100 });
|
||||
assertEquals(10, yAxisDimension.getYAxisDimension(0, 15)[0]);
|
||||
assertEquals(10, yAxisDimension.getYAxisDimension(0, 50)[0]);
|
||||
assertEquals(50, yAxisDimension.getYAxisDimension(0, 111)[0]);
|
||||
assertEquals(50, yAxisDimension.getYAxisDimension(0, 250)[0]);
|
||||
assertEquals(100, yAxisDimension.getYAxisDimension(0, 251)[0]);
|
||||
assertEquals(100, yAxisDimension.getYAxisDimension(0, 10000)[0]);
|
||||
}
|
||||
|
||||
public void testYAxisDimension_minNotAligned() {
|
||||
YAxisDimension settings = new YAxisDimension(
|
||||
5, Integer.MIN_VALUE, Integer.MAX_VALUE, new int[] { 10, 50, 100 });
|
||||
assertEquals(50, settings.getYAxisDimension(5, 55)[0]);
|
||||
assertEquals(10, settings.getYAxisDimension(10, 60)[0]);
|
||||
assertEquals(50, settings.getYAxisDimension(7, 250)[0]);
|
||||
assertEquals(100, settings.getYAxisDimension(7, 257)[0]);
|
||||
assertEquals(100, settings.getYAxisDimension(11, 10000)[0]);
|
||||
assertEquals(200, series.getMinMarkerValue());
|
||||
assertEquals(700, series.getMaxMarkerValue());
|
||||
}
|
||||
}
|
||||
|
||||
+38
-36
@@ -52,31 +52,32 @@ public class ChartFragmentTest extends AndroidTestCase {
|
||||
|
||||
// No input.
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(Double.NaN, point[3]);
|
||||
assertEquals(Double.NaN, point[4]);
|
||||
assertEquals(Double.NaN, point[5]);
|
||||
assertEquals(Double.NaN, point[ChartView.HEART_RATE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.CADENCE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.POWER_SERIES + 1]);
|
||||
|
||||
// Input incorrect state.
|
||||
// Creates SensorData.
|
||||
Sensor.SensorData.Builder powerData = Sensor.SensorData.newBuilder()
|
||||
.setValue(20).setState(Sensor.SensorState.NONE);
|
||||
Sensor.SensorData.Builder cadenceData = Sensor.SensorData.newBuilder()
|
||||
.setValue(20).setState(Sensor.SensorState.NONE);
|
||||
Sensor.SensorData.Builder heartRateData = Sensor.SensorData.newBuilder()
|
||||
.setValue(20).setState(Sensor.SensorState.NONE);
|
||||
.setValue(100).setState(Sensor.SensorState.NONE);
|
||||
Sensor.SensorData.Builder cadenceData = Sensor.SensorData.newBuilder()
|
||||
.setValue(101).setState(Sensor.SensorState.NONE);
|
||||
Sensor.SensorData.Builder powerData = Sensor.SensorData.newBuilder()
|
||||
.setValue(102).setState(Sensor.SensorState.NONE);
|
||||
|
||||
// Creates SensorDataSet.
|
||||
SensorDataSet sensorDataSet = myTracksLocation.getSensorDataSet();
|
||||
sensorDataSet = sensorDataSet.toBuilder()
|
||||
.setPower(powerData)
|
||||
.setCadence(cadenceData)
|
||||
.setHeartRate(heartRateData)
|
||||
.setCadence(cadenceData)
|
||||
.setPower(powerData)
|
||||
.build();
|
||||
myTracksLocation.setSensorData(sensorDataSet);
|
||||
// Test.
|
||||
point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(Double.NaN, point[3]);
|
||||
assertEquals(Double.NaN, point[4]);
|
||||
assertEquals(Double.NaN, point[5]);
|
||||
assertEquals(Double.NaN, point[ChartView.HEART_RATE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.CADENCE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.POWER_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,31 +88,31 @@ public class ChartFragmentTest extends AndroidTestCase {
|
||||
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
|
||||
// No input.
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(Double.NaN, point[3]);
|
||||
assertEquals(Double.NaN, point[4]);
|
||||
assertEquals(Double.NaN, point[5]);
|
||||
assertEquals(Double.NaN, point[ChartView.HEART_RATE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.CADENCE_SERIES + 1]);
|
||||
assertEquals(Double.NaN, point[ChartView.POWER_SERIES + 1]);
|
||||
|
||||
// Creates SensorData.
|
||||
Sensor.SensorData.Builder powerData = Sensor.SensorData.newBuilder()
|
||||
.setValue(20).setState(Sensor.SensorState.SENDING);
|
||||
Sensor.SensorData.Builder cadenceData = Sensor.SensorData.newBuilder()
|
||||
.setValue(20).setState(Sensor.SensorState.SENDING);
|
||||
Sensor.SensorData.Builder heartRateData = Sensor.SensorData.newBuilder()
|
||||
.setValue(20).setState(Sensor.SensorState.SENDING);
|
||||
.setValue(100).setState(Sensor.SensorState.SENDING);
|
||||
Sensor.SensorData.Builder cadenceData = Sensor.SensorData.newBuilder()
|
||||
.setValue(101).setState(Sensor.SensorState.SENDING);
|
||||
Sensor.SensorData.Builder powerData = Sensor.SensorData.newBuilder()
|
||||
.setValue(102).setState(Sensor.SensorState.SENDING);
|
||||
|
||||
// Creates SensorDataSet.
|
||||
SensorDataSet sensorDataSet = myTracksLocation.getSensorDataSet();
|
||||
sensorDataSet = sensorDataSet.toBuilder()
|
||||
.setPower(powerData)
|
||||
.setCadence(cadenceData)
|
||||
.setHeartRate(heartRateData)
|
||||
.setCadence(cadenceData)
|
||||
.setPower(powerData)
|
||||
.build();
|
||||
myTracksLocation.setSensorData(sensorDataSet);
|
||||
// Test.
|
||||
point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(20.0, point[3]);
|
||||
assertEquals(20.0, point[4]);
|
||||
assertEquals(20.0, point[5]);
|
||||
assertEquals(100.0, point[ChartView.HEART_RATE_SERIES + 1]);
|
||||
assertEquals(101.0, point[ChartView.CADENCE_SERIES + 1]);
|
||||
assertEquals(102.0, point[ChartView.POWER_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -230,7 +231,7 @@ public class ChartFragmentTest extends AndroidTestCase {
|
||||
* parameter. Then only one value INITIALLONGTITUDE in buffer.
|
||||
*/
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation1);
|
||||
assertEquals(TrackStubUtils.INITIAL_ALTITUDE, point[1]);
|
||||
assertEquals(TrackStubUtils.INITIAL_ALTITUDE, point[ChartView.ELEVATION_SERIES + 1]);
|
||||
|
||||
/*
|
||||
* Send another value to buffer, now there are two values, INITIALALTITUDE
|
||||
@@ -239,8 +240,8 @@ public class ChartFragmentTest extends AndroidTestCase {
|
||||
MyTracksLocation myTracksLocation2 = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation2.setAltitude(TrackStubUtils.INITIAL_ALTITUDE * 2);
|
||||
point = fillDataPointTestHelper(myTracksLocation2);
|
||||
assertEquals(
|
||||
(TrackStubUtils.INITIAL_ALTITUDE + TrackStubUtils.INITIAL_ALTITUDE * 2) / 2.0, point[1]);
|
||||
assertEquals((TrackStubUtils.INITIAL_ALTITUDE + TrackStubUtils.INITIAL_ALTITUDE * 2) / 2.0,
|
||||
point[ChartView.ELEVATION_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -260,7 +261,7 @@ public class ChartFragmentTest extends AndroidTestCase {
|
||||
MyTracksLocation myTracksLocation1 = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation1.setSpeed(129);
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation1);
|
||||
assertEquals(0.0, point[2]);
|
||||
assertEquals(0.0, point[ChartView.SPEED_SERIES + 1]);
|
||||
|
||||
/*
|
||||
* Tests the logic when both metricUnits and reportSpeed are true.This
|
||||
@@ -275,7 +276,7 @@ public class ChartFragmentTest extends AndroidTestCase {
|
||||
myTracksLocation2.setTime(myTracksLocation1.getTime() + 222);
|
||||
myTracksLocation2.setSpeed(130);
|
||||
point = fillDataPointTestHelper(myTracksLocation2);
|
||||
assertEquals(130.0 * UnitConversions.MS_TO_KMH, point[2]);
|
||||
assertEquals(130.0 * UnitConversions.MS_TO_KMH, point[ChartView.SPEED_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -287,7 +288,8 @@ public class ChartFragmentTest extends AndroidTestCase {
|
||||
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation.setSpeed(132);
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(132.0 * UnitConversions.MS_TO_KMH * UnitConversions.KM_TO_MI, point[2]);
|
||||
assertEquals(132.0 * UnitConversions.MS_TO_KMH * UnitConversions.KM_TO_MI,
|
||||
point[ChartView.SPEED_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -299,8 +301,8 @@ public class ChartFragmentTest extends AndroidTestCase {
|
||||
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation.setSpeed(134);
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(HOURS_PER_UNIT / (134.0 * UnitConversions.MS_TO_KMH), point[2]);
|
||||
|
||||
assertEquals(
|
||||
HOURS_PER_UNIT / (134.0 * UnitConversions.MS_TO_KMH), point[ChartView.PACE_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -313,7 +315,7 @@ public class ChartFragmentTest extends AndroidTestCase {
|
||||
MyTracksLocation myTracksLocation = TrackStubUtils.createMyTracksLocation();
|
||||
myTracksLocation.setSpeed(0);
|
||||
double[] point = fillDataPointTestHelper(myTracksLocation);
|
||||
assertEquals(0.0, point[2]);
|
||||
assertEquals(0.0, point[ChartView.PACE_SERIES + 1]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -323,7 +325,7 @@ public class ChartFragmentTest extends AndroidTestCase {
|
||||
* @return data of this location
|
||||
*/
|
||||
private double[] fillDataPointTestHelper(Location location) {
|
||||
double[] point = new double[6];
|
||||
double[] point = new double[ChartView.NUM_SERIES + 1];
|
||||
chartFragment.fillDataPoint(location, point);
|
||||
return point;
|
||||
}
|
||||
|
||||
+3
@@ -46,6 +46,7 @@ public class UploadResultActivityTest
|
||||
*/
|
||||
public void testAllSuccess() {
|
||||
initialActivity(true, true, true, true, true, true);
|
||||
uploadResultActivity.showDialog(UploadResultActivity.DIALOG_RESULT_ID);
|
||||
Dialog dialog = uploadResultActivity.getDialog();
|
||||
TextView textView = (TextView) dialog.findViewById(R.id.upload_result_success_footer);
|
||||
assertTrue(textView.isShown());
|
||||
@@ -57,6 +58,7 @@ public class UploadResultActivityTest
|
||||
public void testAllFailed() {
|
||||
// Send all kinds but all failed.
|
||||
initialActivity(true, true, true, false, false, false);
|
||||
uploadResultActivity.showDialog(UploadResultActivity.DIALOG_RESULT_ID);
|
||||
Dialog dialog = uploadResultActivity.getDialog();
|
||||
TextView textView = (TextView) dialog.findViewById(R.id.upload_result_error_footer);
|
||||
assertTrue(textView.isShown());
|
||||
@@ -72,6 +74,7 @@ public class UploadResultActivityTest
|
||||
*/
|
||||
public void testPartialSuccess() {
|
||||
initialActivity(true, false, true, true, false, false);
|
||||
uploadResultActivity.showDialog(UploadResultActivity.DIALOG_RESULT_ID);
|
||||
Dialog dialog = uploadResultActivity.getDialog();
|
||||
TextView textView = (TextView) dialog.findViewById(R.id.upload_result_error_footer);
|
||||
assertTrue(textView.isShown());
|
||||
|
||||
Reference in New Issue
Block a user