mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2025-01-23 00:21:43 +01:00
New players / day query
This commit is contained in:
parent
cb626145fe
commit
a454091b7a
@ -120,4 +120,47 @@ public class PlayerCountQueries {
|
||||
|
||||
return queryPlayerCount(sql, after, before, serverUUID);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a EpochMs - Count map of new players on a server.
|
||||
*
|
||||
* @param after After epoch ms
|
||||
* @param before Before epoch ms
|
||||
* @param timeZoneOffset Offset from {@link java.util.TimeZone#getOffset(long)}, applied to the dates before grouping.
|
||||
* @param serverUUID UUID of the Plan server
|
||||
* @return Map: Epoch ms (Accuracy of a day) - How many new players joined that day
|
||||
*/
|
||||
public static Query<NavigableMap<Long, Integer>> newPlayerCounts(long after, long before, long timeZoneOffset, UUID serverUUID) {
|
||||
return database -> {
|
||||
Sql sql = database.getType().getSql();
|
||||
String selectNewPlayersQuery = SELECT +
|
||||
sql.dateToEpochSecond(sql.dateToDayStamp(sql.epochSecondToDate('(' + UserInfoTable.REGISTERED + "+?)/1000"))) +
|
||||
"*1000 as date," +
|
||||
"COUNT(1) as player_count" +
|
||||
FROM + UserInfoTable.TABLE_NAME +
|
||||
WHERE + UserInfoTable.REGISTERED + "<=?" +
|
||||
AND + UserInfoTable.REGISTERED + ">=?" +
|
||||
AND + UserInfoTable.SERVER_UUID + "=?" +
|
||||
GROUP_BY + "date";
|
||||
|
||||
return database.query(new QueryStatement<NavigableMap<Long, Integer>>(selectNewPlayersQuery, 100) {
|
||||
@Override
|
||||
public void prepare(PreparedStatement statement) throws SQLException {
|
||||
statement.setLong(1, timeZoneOffset);
|
||||
statement.setLong(2, before);
|
||||
statement.setLong(3, after);
|
||||
statement.setString(4, serverUUID.toString());
|
||||
}
|
||||
|
||||
@Override
|
||||
public NavigableMap<Long, Integer> processResults(ResultSet set) throws SQLException {
|
||||
NavigableMap<Long, Integer> newPerDay = new TreeMap<>();
|
||||
while (set.next()) {
|
||||
newPerDay.put(set.getLong("date"), set.getInt("player_count"));
|
||||
}
|
||||
return newPerDay;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
@ -19,14 +19,12 @@ package com.djrapitops.plan.system.json;
|
||||
import com.djrapitops.plan.data.container.Ping;
|
||||
import com.djrapitops.plan.data.store.mutators.MutatorFunctions;
|
||||
import com.djrapitops.plan.data.store.mutators.PingMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.TPSMutator;
|
||||
import com.djrapitops.plan.data.store.objects.DateMap;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.db.Database;
|
||||
import com.djrapitops.plan.db.access.queries.analysis.ActivityIndexQueries;
|
||||
import com.djrapitops.plan.db.access.queries.analysis.PlayerCountQueries;
|
||||
import com.djrapitops.plan.db.access.queries.containers.ServerPlayerContainersQuery;
|
||||
import com.djrapitops.plan.db.access.queries.objects.GeoInfoQueries;
|
||||
import com.djrapitops.plan.db.access.queries.objects.PingQueries;
|
||||
import com.djrapitops.plan.db.access.queries.objects.TPSQueries;
|
||||
@ -98,17 +96,20 @@ public class GraphJSONParser {
|
||||
NavigableMap<Long, Integer> uniquePerDay = db.query(
|
||||
PlayerCountQueries.uniquePlayerCounts(halfYearAgo, now, timeZone.getOffset(now), serverUUID)
|
||||
);
|
||||
PlayersMutator playersMutator = new PlayersMutator(db.query(new ServerPlayerContainersQuery(serverUUID)))
|
||||
.filterRegisteredBetween(halfYearAgo, now);
|
||||
NavigableMap<Long, Integer> newPerDay = db.query(
|
||||
PlayerCountQueries.newPlayerCounts(halfYearAgo, now, timeZone.getOffset(now), serverUUID)
|
||||
);
|
||||
|
||||
return "{\"uniquePlayers\":" +
|
||||
lineGraphs.lineGraph(
|
||||
MutatorFunctions.toPointsWithRemovedOffset(
|
||||
MutatorFunctions.addMissing(uniquePerDay, TimeUnit.DAYS.toMillis(1L), 0),
|
||||
timeZone
|
||||
)).toHighChartsSeries() +
|
||||
lineGraphs.lineGraph(MutatorFunctions.toPointsWithRemovedOffset(
|
||||
MutatorFunctions.addMissing(uniquePerDay, TimeUnit.DAYS.toMillis(1L), 0),
|
||||
timeZone
|
||||
)).toHighChartsSeries() +
|
||||
",\"newPlayers\":" +
|
||||
lineGraphs.lineGraph(MutatorFunctions.toPointsWithRemovedOffset(playersMutator.newPerDay(timeZone), timeZone)).toHighChartsSeries() +
|
||||
lineGraphs.lineGraph(MutatorFunctions.toPointsWithRemovedOffset(
|
||||
MutatorFunctions.addMissing(newPerDay, TimeUnit.DAYS.toMillis(1L), 0),
|
||||
timeZone
|
||||
)).toHighChartsSeries() +
|
||||
'}';
|
||||
}
|
||||
|
||||
@ -119,13 +120,13 @@ public class GraphJSONParser {
|
||||
NavigableMap<Long, Integer> uniquePerDay = db.query(
|
||||
PlayerCountQueries.uniquePlayerCounts(twoYearsAgo, now, timeZone.getOffset(now), serverUUID)
|
||||
);
|
||||
PlayersMutator playersMutator = new PlayersMutator(db.query(new ServerPlayerContainersQuery(serverUUID)));
|
||||
|
||||
NavigableMap<Long, Integer> newPerDay = db.query(
|
||||
PlayerCountQueries.newPlayerCounts(twoYearsAgo, now, timeZone.getOffset(now), serverUUID)
|
||||
);
|
||||
return "{\"data\":" +
|
||||
graphs.calendar().serverCalendar(
|
||||
playersMutator,
|
||||
uniquePerDay,
|
||||
playersMutator.newPerDay(timeZone)
|
||||
newPerDay
|
||||
).toCalendarSeries() +
|
||||
",\"firstDay\":" + 1 + '}';
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ public class TimeAmountFormatter implements Formatter<Long> {
|
||||
|
||||
@Override
|
||||
public String apply(Long ms) {
|
||||
if (ms < 0) {
|
||||
if (ms == null || ms < 0) {
|
||||
return "-";
|
||||
}
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -17,7 +17,6 @@
|
||||
package com.djrapitops.plan.utilities.html.graphs.calendar;
|
||||
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
||||
import com.djrapitops.plan.system.settings.config.PlanConfig;
|
||||
import com.djrapitops.plan.system.settings.paths.TimeSettings;
|
||||
import com.djrapitops.plan.system.settings.theme.Theme;
|
||||
@ -59,12 +58,11 @@ public class CalendarFactory {
|
||||
}
|
||||
|
||||
public ServerCalendar serverCalendar(
|
||||
PlayersMutator mutator,
|
||||
SortedMap<Long, Integer> uniquePerDay,
|
||||
SortedMap<Long, Integer> newPerDay
|
||||
) {
|
||||
return new ServerCalendar(
|
||||
mutator, uniquePerDay, newPerDay,
|
||||
uniquePerDay, newPerDay,
|
||||
formatters.iso8601NoClockLong(), formatters.timeAmount(), theme,
|
||||
config.get(TimeSettings.USE_SERVER_TIME) ? TimeZone.getDefault() : TimeZone.getTimeZone("GMT")
|
||||
);
|
||||
|
@ -16,9 +16,6 @@
|
||||
*/
|
||||
package com.djrapitops.plan.utilities.html.graphs.calendar;
|
||||
|
||||
import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.store.mutators.PlayersMutator;
|
||||
import com.djrapitops.plan.data.store.mutators.SessionsMutator;
|
||||
import com.djrapitops.plan.system.settings.theme.Theme;
|
||||
import com.djrapitops.plan.system.settings.theme.ThemeVal;
|
||||
import com.djrapitops.plan.utilities.formatting.Formatter;
|
||||
@ -32,9 +29,10 @@ import java.util.*;
|
||||
*/
|
||||
public class ServerCalendar {
|
||||
|
||||
private final PlayersMutator mutator;
|
||||
private final SortedMap<Long, Integer> uniquePerDay;
|
||||
private final SortedMap<Long, Integer> newPerDay;
|
||||
private final SortedMap<Long, Integer> sessionsPerDay;
|
||||
private final SortedMap<Long, Long> playtimePerDay;
|
||||
|
||||
private final Formatter<Long> iso8601Formatter;
|
||||
private final Formatter<Long> timeAmountFormatter;
|
||||
@ -42,17 +40,18 @@ public class ServerCalendar {
|
||||
private final TimeZone timeZone;
|
||||
|
||||
ServerCalendar(
|
||||
PlayersMutator mutator, SortedMap<Long, Integer> uniquePerDay, SortedMap<Long, Integer> newPerDay,
|
||||
SortedMap<Long, Integer> uniquePerDay, SortedMap<Long, Integer> newPerDay,
|
||||
Formatter<Long> iso8601Formatter,
|
||||
Formatter<Long> timeAmountFormatter,
|
||||
Theme theme,
|
||||
TimeZone timeZone
|
||||
) {
|
||||
this.mutator = mutator;
|
||||
this.uniquePerDay = uniquePerDay;
|
||||
this.newPerDay = newPerDay;
|
||||
this.iso8601Formatter = iso8601Formatter;
|
||||
this.timeAmountFormatter = timeAmountFormatter;
|
||||
sessionsPerDay = new TreeMap<>(); // TODO
|
||||
playtimePerDay = new TreeMap<>(); // TODO
|
||||
this.theme = theme;
|
||||
this.timeZone = timeZone;
|
||||
}
|
||||
@ -87,10 +86,6 @@ public class ServerCalendar {
|
||||
}
|
||||
|
||||
private void appendSessionRelatedData(StringBuilder series) {
|
||||
SessionsMutator sessionsMutator = new SessionsMutator(mutator.getSessions());
|
||||
// Adds a timezone offset
|
||||
SortedMap<Long, List<Session>> byStartOfDay = sessionsMutator.toDateHoldersMutator().groupByStartOfDay(timeZone);
|
||||
|
||||
// Has a timezone offset
|
||||
for (Map.Entry<Long, Integer> entry : uniquePerDay.entrySet()) {
|
||||
if (entry.getValue() <= 0) {
|
||||
@ -99,26 +94,28 @@ public class ServerCalendar {
|
||||
|
||||
Long key = entry.getKey();
|
||||
String day = iso8601Formatter.apply(key - timeZone.getOffset(entry.getKey()));// Remove the timezone offset since Calendar uses UTC
|
||||
List<Session> sessions = byStartOfDay.getOrDefault(key, new ArrayList<>());
|
||||
|
||||
SessionsMutator dayMutator = new SessionsMutator(sessions);
|
||||
long sessionCount = dayMutator.count();
|
||||
long playtime = dayMutator.toPlaytime();
|
||||
Integer sessionCount = sessionsPerDay.getOrDefault(key, 0);
|
||||
Long playtime = playtimePerDay.getOrDefault(key, 0L);
|
||||
long uniquePlayers = entry.getValue();
|
||||
|
||||
series.append(",{\"title\": \"Playtime: ").append(timeAmountFormatter.apply(playtime))
|
||||
.append("\",\"start\":\"").append(day)
|
||||
.append("\",\"color\": \"").append(theme.getValue(ThemeVal.GREEN)).append('"')
|
||||
.append("}");
|
||||
|
||||
series.append(",{\"title\": \"Sessions: ").append(sessionCount)
|
||||
.append("\",\"start\":\"").append(day)
|
||||
.append("\",\"color\": \"").append(theme.getValue(ThemeVal.TEAL)).append('"')
|
||||
.append("}");
|
||||
if (playtime > 0) {
|
||||
series.append(",{\"title\": \"Playtime: ").append(timeAmountFormatter.apply(playtime))
|
||||
.append("\",\"start\":\"").append(day)
|
||||
.append("\",\"color\": \"").append(theme.getValue(ThemeVal.GREEN)).append('"')
|
||||
.append("}");
|
||||
}
|
||||
if (sessionCount > 0) {
|
||||
series.append(",{\"title\": \"Sessions: ").append(sessionCount)
|
||||
.append("\",\"start\":\"").append(day)
|
||||
.append("\",\"color\": \"").append(theme.getValue(ThemeVal.TEAL)).append('"')
|
||||
.append("}");
|
||||
}
|
||||
|
||||
series.append(",{\"title\": \"Unique: ").append(uniquePlayers)
|
||||
.append("\",\"start\":\"").append(day)
|
||||
.append("\"}");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user