Aggregated stats: ordered by number number of tracks per category.

This commit is contained in:
Dennis Guse
2020-12-13 22:44:44 +01:00
parent e1e7c24d9f
commit 5675dc800d
4 changed files with 59 additions and 50 deletions
@@ -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();