forked from upstream-mirrors/OpenTracks
Aggregated stats: ordered by number number of tracks per category.
This commit is contained in:
+21
-27
@@ -8,6 +8,8 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.JUnit4;
|
import org.junit.runners.JUnit4;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import de.dennisguse.opentracks.R;
|
import de.dennisguse.opentracks.R;
|
||||||
import de.dennisguse.opentracks.content.data.Track;
|
import de.dennisguse.opentracks.content.data.Track;
|
||||||
import de.dennisguse.opentracks.stats.TrackStatistics;
|
import de.dennisguse.opentracks.stats.TrackStatistics;
|
||||||
@@ -57,8 +59,7 @@ public class AggregatedStatisticsTest {
|
|||||||
Track track = createTrack(context, totalDistance, totalTime, biking);
|
Track track = createTrack(context, totalDistance, totalTime, biking);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics(List.of(track));
|
||||||
aggregatedStatistics.aggregate(track);
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertEquals(1, aggregatedStatistics.getCount());
|
assertEquals(1, aggregatedStatistics.getCount());
|
||||||
@@ -80,8 +81,7 @@ public class AggregatedStatisticsTest {
|
|||||||
Track track = createTrack(context, totalDistance, totalTime, mountainBiking);
|
Track track = createTrack(context, totalDistance, totalTime, mountainBiking);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics(List.of(track));
|
||||||
aggregatedStatistics.aggregate(track);
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertNotNull(aggregatedStatistics.get(mountainBiking));
|
assertNotNull(aggregatedStatistics.get(mountainBiking));
|
||||||
@@ -97,8 +97,7 @@ public class AggregatedStatisticsTest {
|
|||||||
Track track = createTrack(context, totalDistance, totalTime, trailRunning);
|
Track track = createTrack(context, totalDistance, totalTime, trailRunning);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics(List.of(track));
|
||||||
aggregatedStatistics.aggregate(track);
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertNotNull(aggregatedStatistics.get(trailRunning));
|
assertNotNull(aggregatedStatistics.get(trailRunning));
|
||||||
@@ -111,15 +110,10 @@ public class AggregatedStatisticsTest {
|
|||||||
long totalDistance = 10000;
|
long totalDistance = 10000;
|
||||||
long totalTime = 2400000;
|
long totalTime = 2400000;
|
||||||
String biking = context.getString(R.string.activity_type_biking);
|
String biking = context.getString(R.string.activity_type_biking);
|
||||||
Track[] tracks = new Track[2];
|
List<Track> tracks = List.of(createTrack(context, totalDistance, totalTime, biking), createTrack(context, totalDistance, totalTime, biking));
|
||||||
for (int i = 0; i < 2; i++) {
|
|
||||||
tracks[i] = createTrack(context, totalDistance, totalTime, biking);
|
|
||||||
}
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics(tracks);
|
||||||
aggregatedStatistics.aggregate(tracks[0]); // biking activity 1.
|
|
||||||
aggregatedStatistics.aggregate(tracks[1]); // biking activity 2.
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertEquals(1, aggregatedStatistics.getCount());
|
assertEquals(1, aggregatedStatistics.getCount());
|
||||||
@@ -141,17 +135,14 @@ public class AggregatedStatisticsTest {
|
|||||||
String running = context.getString(R.string.activity_type_running);
|
String running = context.getString(R.string.activity_type_running);
|
||||||
String walking = context.getString(R.string.activity_type_walking);
|
String walking = context.getString(R.string.activity_type_walking);
|
||||||
long totalTime = 2400000;
|
long totalTime = 2400000;
|
||||||
Track[] tracks = new Track[]{
|
List<Track> tracks = List.of(
|
||||||
createTrack(context, totalDistance, totalTime, biking),
|
createTrack(context, totalDistance, totalTime, biking),
|
||||||
createTrack(context, totalDistance, totalTime, running),
|
createTrack(context, totalDistance, totalTime, running),
|
||||||
createTrack(context, totalDistance, totalTime, walking)
|
createTrack(context, totalDistance, totalTime, walking)
|
||||||
};
|
);
|
||||||
|
|
||||||
// when
|
// when
|
||||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics(tracks);
|
||||||
aggregatedStatistics.aggregate(tracks[0]); // biking activity 1.
|
|
||||||
aggregatedStatistics.aggregate(tracks[1]); // biking activity 2.
|
|
||||||
aggregatedStatistics.aggregate(tracks[2]); // biking activity 3.
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
assertEquals(3, aggregatedStatistics.getCount());
|
assertEquals(3, aggregatedStatistics.getCount());
|
||||||
@@ -191,7 +182,7 @@ public class AggregatedStatisticsTest {
|
|||||||
String running = context.getString(R.string.activity_type_running);
|
String running = context.getString(R.string.activity_type_running);
|
||||||
String walking = context.getString(R.string.activity_type_walking);
|
String walking = context.getString(R.string.activity_type_walking);
|
||||||
String driving = context.getString(R.string.activity_type_driving);
|
String driving = context.getString(R.string.activity_type_driving);
|
||||||
Track[] tracks = new Track[]{
|
List<Track> tracks = List.of(
|
||||||
createTrack(context, totalDistance, totalTime, biking),
|
createTrack(context, totalDistance, totalTime, biking),
|
||||||
createTrack(context, totalDistance, totalTime, running),
|
createTrack(context, totalDistance, totalTime, running),
|
||||||
createTrack(context, totalDistance, totalTime, walking),
|
createTrack(context, totalDistance, totalTime, walking),
|
||||||
@@ -201,16 +192,12 @@ public class AggregatedStatisticsTest {
|
|||||||
createTrack(context, totalDistance, totalTime, biking),
|
createTrack(context, totalDistance, totalTime, biking),
|
||||||
createTrack(context, totalDistance, totalTime, biking),
|
createTrack(context, totalDistance, totalTime, biking),
|
||||||
createTrack(context, totalDistance, totalTime, biking),
|
createTrack(context, totalDistance, totalTime, biking),
|
||||||
createTrack(context, totalDistance, totalTime, driving),
|
createTrack(context, totalDistance, totalTime, driving)
|
||||||
};
|
);
|
||||||
|
|
||||||
|
|
||||||
// when
|
// when
|
||||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics(tracks);
|
||||||
for (Track track : tracks) {
|
|
||||||
aggregatedStatistics.aggregate(track);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// then
|
// then
|
||||||
// 4 sports.
|
// 4 sports.
|
||||||
@@ -255,5 +242,12 @@ public class AggregatedStatisticsTest {
|
|||||||
assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
|
assertEquals(totalDistance, statistics2.getTotalDistance(), 0);
|
||||||
assertEquals(totalTime, statistics2.getMovingTime());
|
assertEquals(totalTime, statistics2.getMovingTime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check order
|
||||||
|
|
||||||
|
{
|
||||||
|
assertEquals(biking, aggregatedStatistics.getItem(0).getCategory());
|
||||||
|
assertEquals(driving, aggregatedStatistics.getItem(3).getCategory());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,17 +62,17 @@ public class AggregatedStatisticsAdapter extends BaseAdapter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSpeedSport(int position) {
|
private boolean isSpeedSport(int position) {
|
||||||
String category = aggregatedStatistics.getSportName(position);
|
String category = aggregatedStatistics.getCategory(position);
|
||||||
return TrackIconUtils.isSpeedIcon(context, category);
|
return TrackIconUtils.isSpeedIcon(context, category);
|
||||||
}
|
}
|
||||||
|
|
||||||
private int getIcon(int position) {
|
private int getIcon(int position) {
|
||||||
String iconValue = TrackIconUtils.getIconValue(context, aggregatedStatistics.getSportName(position));
|
String iconValue = TrackIconUtils.getIconValue(context, aggregatedStatistics.getCategory(position));
|
||||||
return TrackIconUtils.getIconDrawable(iconValue);
|
return TrackIconUtils.getIconDrawable(iconValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getName(int position) {
|
private String getName(int position) {
|
||||||
return aggregatedStatistics.getSportName(position);
|
return aggregatedStatistics.getCategory(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ViewHolder {
|
private class ViewHolder {
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
package de.dennisguse.opentracks.viewmodels;
|
package de.dennisguse.opentracks.viewmodels;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.VisibleForTesting;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -10,50 +14,62 @@ import de.dennisguse.opentracks.stats.TrackStatistics;
|
|||||||
|
|
||||||
public class AggregatedStatistics {
|
public class AggregatedStatistics {
|
||||||
|
|
||||||
private final Map<String, AggregatedStatistic> aggregatedStatistics = new HashMap<>();
|
private final Map<String, AggregatedStatistic> dataMap = new HashMap<>();
|
||||||
|
|
||||||
public void aggregate(List<Track> tracks) {
|
private final List<AggregatedStatistic> dataList = new ArrayList<>();
|
||||||
|
|
||||||
|
public AggregatedStatistics(@NonNull List<Track> tracks) {
|
||||||
for (Track track : tracks) {
|
for (Track track : tracks) {
|
||||||
aggregate(track);
|
aggregate(track);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dataList.addAll(dataMap.values());
|
||||||
|
Collections.sort(dataList, (o1, o2) -> {
|
||||||
|
if (o1.getCountTracks() == o2.getCountTracks()) {
|
||||||
|
return o1.getCategory().compareTo(o2.getCategory());
|
||||||
|
}
|
||||||
|
return (o1.getCountTracks() < o2.getCountTracks() ? 1 : -1);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void aggregate(Track track) {
|
@VisibleForTesting
|
||||||
|
public void aggregate(@NonNull Track track) {
|
||||||
String category = track.getCategory();
|
String category = track.getCategory();
|
||||||
if (aggregatedStatistics.containsKey(category)) {
|
if (dataMap.containsKey(category)) {
|
||||||
aggregatedStatistics.get(category).add(track.getTrackStatistics());
|
dataMap.get(category).add(track.getTrackStatistics());
|
||||||
} else {
|
} else {
|
||||||
aggregatedStatistics.put(category, new AggregatedStatistic(track.getTrackStatistics()));
|
dataMap.put(category, new AggregatedStatistic(category, track.getTrackStatistics()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getCount() {
|
public int getCount() {
|
||||||
return aggregatedStatistics.size();
|
return dataMap.size();
|
||||||
}
|
|
||||||
|
|
||||||
public String getSportName(int position) {
|
|
||||||
return getKey(position);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public AggregatedStatistic get(String category) {
|
public AggregatedStatistic get(String category) {
|
||||||
return aggregatedStatistics.get(category);
|
return dataMap.get(category);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getKey(int position) {
|
public String getCategory(int position) {
|
||||||
return (new ArrayList<>(aggregatedStatistics.keySet())).get(position);
|
return dataList.get(position).getCategory();
|
||||||
}
|
}
|
||||||
|
|
||||||
public AggregatedStatistic getItem(int position) {
|
public AggregatedStatistic getItem(int position) {
|
||||||
return (new ArrayList<>(aggregatedStatistics.values())).get(position);
|
return dataList.get(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class AggregatedStatistic {
|
public static class AggregatedStatistic {
|
||||||
|
private final String category;
|
||||||
private final TrackStatistics trackStatistics;
|
private final TrackStatistics trackStatistics;
|
||||||
private int countTracks;
|
private int countTracks = 1;
|
||||||
|
|
||||||
public AggregatedStatistic(TrackStatistics trackStatistics) {
|
public AggregatedStatistic(String category, TrackStatistics trackStatistics) {
|
||||||
|
this.category = category;
|
||||||
this.trackStatistics = trackStatistics;
|
this.trackStatistics = trackStatistics;
|
||||||
this.countTracks = 1;
|
}
|
||||||
|
|
||||||
|
public String getCategory() {
|
||||||
|
return category;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TrackStatistics getTrackStatistics() {
|
public TrackStatistics getTrackStatistics() {
|
||||||
|
|||||||
@@ -33,8 +33,7 @@ public class AggregatedStatisticsModel extends AndroidViewModel {
|
|||||||
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getApplication().getApplicationContext());
|
ContentProviderUtils contentProviderUtils = new ContentProviderUtils(getApplication().getApplicationContext());
|
||||||
List<Track> tracks = contentProviderUtils.getTracks();
|
List<Track> tracks = contentProviderUtils.getTracks();
|
||||||
|
|
||||||
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics();
|
AggregatedStatistics aggregatedStatistics = new AggregatedStatistics(tracks);
|
||||||
aggregatedStatistics.aggregate(tracks);
|
|
||||||
|
|
||||||
aggregatedStats.postValue(aggregatedStatistics);
|
aggregatedStats.postValue(aggregatedStatistics);
|
||||||
}).start();
|
}).start();
|
||||||
|
|||||||
Reference in New Issue
Block a user