Plan/Plan/common/src/main/java/com/djrapitops/plan/delivery/rendering/json/graphs/GraphJSONCreator.java

549 lines
27 KiB
Java

/*
* This file is part of Player Analytics (Plan).
*
* Plan is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License v3 as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Plan is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Plan. If not, see <https://www.gnu.org/licenses/>.
*/
package com.djrapitops.plan.delivery.rendering.json.graphs;
import com.djrapitops.plan.delivery.domain.DateMap;
import com.djrapitops.plan.delivery.domain.DateObj;
import com.djrapitops.plan.delivery.domain.JoinAddressCount;
import com.djrapitops.plan.delivery.domain.JoinAddressCounts;
import com.djrapitops.plan.delivery.domain.datatransfer.ServerDto;
import com.djrapitops.plan.delivery.domain.datatransfer.graphs.GraphCollection;
import com.djrapitops.plan.delivery.domain.datatransfer.graphs.ServerSpecificLineGraph;
import com.djrapitops.plan.delivery.domain.mutators.MutatorFunctions;
import com.djrapitops.plan.delivery.domain.mutators.PingMutator;
import com.djrapitops.plan.delivery.domain.mutators.TPSMutator;
import com.djrapitops.plan.delivery.rendering.json.graphs.bar.BarGraph;
import com.djrapitops.plan.delivery.rendering.json.graphs.line.LineGraph;
import com.djrapitops.plan.delivery.rendering.json.graphs.line.LineGraphFactory;
import com.djrapitops.plan.delivery.rendering.json.graphs.line.PingGraph;
import com.djrapitops.plan.delivery.rendering.json.graphs.line.Point;
import com.djrapitops.plan.delivery.rendering.json.graphs.pie.Pie;
import com.djrapitops.plan.delivery.rendering.json.graphs.pie.PieSlice;
import com.djrapitops.plan.delivery.rendering.json.graphs.pie.WorldPie;
import com.djrapitops.plan.delivery.rendering.json.graphs.special.WorldMap;
import com.djrapitops.plan.delivery.rendering.json.graphs.stack.StackGraph;
import com.djrapitops.plan.gathering.domain.FinishedSession;
import com.djrapitops.plan.gathering.domain.Ping;
import com.djrapitops.plan.gathering.domain.WorldTimes;
import com.djrapitops.plan.identification.Server;
import com.djrapitops.plan.identification.ServerUUID;
import com.djrapitops.plan.settings.config.PlanConfig;
import com.djrapitops.plan.settings.config.paths.DataGatheringSettings;
import com.djrapitops.plan.settings.config.paths.DisplaySettings;
import com.djrapitops.plan.settings.config.paths.TimeSettings;
import com.djrapitops.plan.settings.locale.Locale;
import com.djrapitops.plan.settings.locale.lang.GenericLang;
import com.djrapitops.plan.settings.theme.Theme;
import com.djrapitops.plan.settings.theme.ThemeVal;
import com.djrapitops.plan.storage.database.DBSystem;
import com.djrapitops.plan.storage.database.Database;
import com.djrapitops.plan.storage.database.queries.analysis.ActivityIndexQueries;
import com.djrapitops.plan.storage.database.queries.analysis.NetworkActivityIndexQueries;
import com.djrapitops.plan.storage.database.queries.analysis.PlayerCountQueries;
import com.djrapitops.plan.storage.database.queries.objects.*;
import com.djrapitops.plan.storage.database.sql.tables.JoinAddressTable;
import com.djrapitops.plan.utilities.comparators.DateHolderOldestComparator;
import com.djrapitops.plan.utilities.comparators.PieSliceComparator;
import com.djrapitops.plan.utilities.java.Lists;
import com.djrapitops.plan.utilities.java.Maps;
import net.playeranalytics.plugin.scheduling.TimeAmount;
import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
/**
* Creates Graph related Data JSON.
*
* @author AuroraLS3
*/
@Singleton
public class GraphJSONCreator {
private final PlanConfig config;
private final Locale locale;
private final Theme theme;
private final DBSystem dbSystem;
private final Graphs graphs;
@Inject
public GraphJSONCreator(
PlanConfig config,
Locale locale,
Theme theme,
DBSystem dbSystem,
Graphs graphs
) {
this.config = config;
this.locale = locale;
this.theme = theme;
this.dbSystem = dbSystem;
this.graphs = graphs;
}
public String performanceGraphJSON(ServerUUID serverUUID) {
long now = System.currentTimeMillis();
Database db = dbSystem.getDatabase();
LineGraphFactory lineGraphs = graphs.line();
long halfYearAgo = now - TimeUnit.DAYS.toMillis(180);
TPSMutator tpsMutator = new TPSMutator(db.query(TPSQueries.fetchTPSDataOfServer(halfYearAgo, now, serverUUID)));
return '{' +
"\"playersOnline\":" + lineGraphs.playersOnlineGraph(tpsMutator).toHighChartsSeries() +
",\"tps\":" + lineGraphs.tpsGraph(tpsMutator).toHighChartsSeries() +
",\"cpu\":" + lineGraphs.cpuGraph(tpsMutator).toHighChartsSeries() +
",\"ram\":" + lineGraphs.ramGraph(tpsMutator).toHighChartsSeries() +
",\"entities\":" + lineGraphs.entityGraph(tpsMutator).toHighChartsSeries() +
",\"chunks\":" + lineGraphs.chunkGraph(tpsMutator).toHighChartsSeries() +
",\"disk\":" + lineGraphs.diskGraph(tpsMutator).toHighChartsSeries() +
",\"colors\":{" +
"\"playersOnline\":\"" + theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE) + "\"," +
"\"cpu\":\"" + theme.getValue(ThemeVal.GRAPH_CPU) + "\"," +
"\"ram\":\"" + theme.getValue(ThemeVal.GRAPH_RAM) + "\"," +
"\"entities\":\"" + theme.getValue(ThemeVal.GRAPH_ENTITIES) + "\"," +
"\"chunks\":\"" + theme.getValue(ThemeVal.GRAPH_CHUNKS) + "\"," +
"\"low\":\"" + theme.getValue(ThemeVal.GRAPH_TPS_LOW) + "\"," +
"\"med\":\"" + theme.getValue(ThemeVal.GRAPH_TPS_MED) + "\"," +
"\"high\":\"" + theme.getValue(ThemeVal.GRAPH_TPS_HIGH) + "\"}" +
",\"zones\":{" +
"\"tpsThresholdMed\":" + config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_MED) + ',' +
"\"tpsThresholdHigh\":" + config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_HIGH) + ',' +
"\"diskThresholdMed\":" + config.get(DisplaySettings.GRAPH_DISK_THRESHOLD_MED) + ',' +
"\"diskThresholdHigh\":" + config.get(DisplaySettings.GRAPH_DISK_THRESHOLD_HIGH) +
"}}";
}
public Map<String, Object> optimizedPerformanceGraphJSON(ServerUUID serverUUID) {
long now = System.currentTimeMillis();
long twoMonthsAgo = now - TimeUnit.DAYS.toMillis(60);
long monthAgo = now - TimeUnit.DAYS.toMillis(30);
long lowestResolution = TimeUnit.MINUTES.toMillis(20);
long lowResolution = TimeUnit.MINUTES.toMillis(5);
Database db = dbSystem.getDatabase();
TPSMutator lowestResolutionData = new TPSMutator(db.query(TPSQueries.fetchTPSDataOfServerInResolution(0, twoMonthsAgo, lowestResolution, serverUUID)));
TPSMutator lowResolutionData = new TPSMutator(db.query(TPSQueries.fetchTPSDataOfServerInResolution(twoMonthsAgo, monthAgo, lowResolution, serverUUID)));
TPSMutator highResolutionData = new TPSMutator(db.query(TPSQueries.fetchTPSDataOfServer(monthAgo, now, serverUUID)));
String serverName = db.query(ServerQueries.fetchServerMatchingIdentifier(serverUUID))
.map(Server::getIdentifiableName)
.orElse(serverUUID.toString());
List<Number[]> values = lowestResolutionData.toArrays(new LineGraph.GapStrategy(
config.isTrue(DisplaySettings.GAPS_IN_GRAPH_DATA),
lowestResolution + TimeUnit.MINUTES.toMillis(1),
TimeUnit.MINUTES.toMillis(1),
TimeUnit.MINUTES.toMillis(30),
null
));
values.addAll(lowResolutionData.toArrays(new LineGraph.GapStrategy(
config.isTrue(DisplaySettings.GAPS_IN_GRAPH_DATA),
lowResolution + TimeUnit.MINUTES.toMillis(1),
TimeUnit.MINUTES.toMillis(1),
TimeUnit.MINUTES.toMillis(30),
null
)));
values.addAll(highResolutionData.toArrays(new LineGraph.GapStrategy(
config.isTrue(DisplaySettings.GAPS_IN_GRAPH_DATA),
TimeUnit.MINUTES.toMillis(3),
TimeUnit.MINUTES.toMillis(1),
TimeUnit.MINUTES.toMillis(30),
null
)));
return Maps.builder(String.class, Object.class)
.put("keys", new String[]{"date", "playersOnline", "tps", "cpu", "ram", "entities", "chunks", "disk"})
.put("values", values)
.put("colors", Maps.builder(String.class, Object.class)
.put("playersOnline", theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE))
.put("cpu", theme.getValue(ThemeVal.GRAPH_CPU))
.put("ram", theme.getValue(ThemeVal.GRAPH_RAM))
.put("entities", theme.getValue(ThemeVal.GRAPH_ENTITIES))
.put("chunks", theme.getValue(ThemeVal.GRAPH_CHUNKS))
.put("low", theme.getValue(ThemeVal.GRAPH_TPS_LOW))
.put("med", theme.getValue(ThemeVal.GRAPH_TPS_MED))
.put("high", theme.getValue(ThemeVal.GRAPH_TPS_HIGH))
.build())
.put("zones", Maps.builder(String.class, Object.class)
.put("tpsThresholdMed", config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_MED))
.put("tpsThresholdHigh", config.get(DisplaySettings.GRAPH_TPS_THRESHOLD_HIGH))
.put("diskThresholdMed", config.get(DisplaySettings.GRAPH_DISK_THRESHOLD_MED))
.put("diskThresholdHigh", config.get(DisplaySettings.GRAPH_DISK_THRESHOLD_HIGH))
.build())
.put("serverName", serverName)
.put("serverUUID", serverUUID)
.build();
}
public String playersOnlineGraph(ServerUUID serverUUID) {
Database db = dbSystem.getDatabase();
long now = System.currentTimeMillis();
long halfYearAgo = now - TimeUnit.DAYS.toMillis(180L);
List<Point> points = Lists.map(
db.query(TPSQueries.fetchPlayersOnlineOfServer(halfYearAgo, now, serverUUID)),
Point::fromDateObj
);
return "{\"playersOnline\":" + graphs.line().lineGraph(points).toHighChartsSeries() +
",\"color\":\"" + theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE) + "\"}";
}
public String uniqueAndNewGraphJSON(ServerUUID serverUUID) {
Database db = dbSystem.getDatabase();
LineGraphFactory lineGraphs = graphs.line();
long now = System.currentTimeMillis();
long halfYearAgo = now - TimeUnit.DAYS.toMillis(180L);
int timeZoneOffset = config.getTimeZone().getOffset(now);
NavigableMap<Long, Integer> uniquePerDay = db.query(
PlayerCountQueries.uniquePlayerCounts(halfYearAgo, now, timeZoneOffset, serverUUID)
);
NavigableMap<Long, Integer> newPerDay = db.query(
PlayerCountQueries.newPlayerCounts(halfYearAgo, now, timeZoneOffset, serverUUID)
);
return createUniqueAndNewJSON(lineGraphs, uniquePerDay, newPerDay, TimeUnit.DAYS.toMillis(1L));
}
public String hourlyUniqueAndNewGraphJSON(ServerUUID serverUUID) {
Database db = dbSystem.getDatabase();
LineGraphFactory lineGraphs = graphs.line();
long now = System.currentTimeMillis();
long weekAgo = now - TimeUnit.DAYS.toMillis(7L);
int timeZoneOffset = config.getTimeZone().getOffset(now);
NavigableMap<Long, Integer> uniquePerDay = db.query(
PlayerCountQueries.hourlyUniquePlayerCounts(weekAgo, now, timeZoneOffset, serverUUID)
);
NavigableMap<Long, Integer> newPerDay = db.query(
PlayerCountQueries.newPlayerCounts(weekAgo, now, timeZoneOffset, serverUUID)
);
return createUniqueAndNewJSON(lineGraphs, uniquePerDay, newPerDay, TimeUnit.HOURS.toMillis(1L));
}
public String createUniqueAndNewJSON(LineGraphFactory lineGraphs, NavigableMap<Long, Integer> uniquePerDay, NavigableMap<Long, Integer> newPerDay, long gapFillPeriod) {
LineGraph.GapStrategy gapStrategy = new LineGraph.GapStrategy(true, gapFillPeriod, 0, gapFillPeriod, 0.0);
return "{\"uniquePlayers\":" +
lineGraphs.lineGraph(MutatorFunctions.toPoints(
MutatorFunctions.addMissing(uniquePerDay, gapFillPeriod, 0)
), gapStrategy).toHighChartsSeries() +
",\"newPlayers\":" +
lineGraphs.lineGraph(MutatorFunctions.toPoints(
MutatorFunctions.addMissing(newPerDay, gapFillPeriod, 0)
), gapStrategy).toHighChartsSeries() +
",\"colors\":{" +
"\"playersOnline\":\"" + theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE) + "\"," +
"\"newPlayers\":\"" + theme.getValue(ThemeVal.LIGHT_GREEN) + "\"" +
"}}";
}
public String uniqueAndNewGraphJSON() {
Database db = dbSystem.getDatabase();
LineGraphFactory lineGraphs = graphs.line();
long now = System.currentTimeMillis();
long halfYearAgo = now - TimeUnit.DAYS.toMillis(180L);
int timeZoneOffset = config.getTimeZone().getOffset(now);
NavigableMap<Long, Integer> uniquePerDay = db.query(
PlayerCountQueries.uniquePlayerCounts(halfYearAgo, now, timeZoneOffset)
);
NavigableMap<Long, Integer> newPerDay = db.query(
PlayerCountQueries.newPlayerCounts(halfYearAgo, now, timeZoneOffset)
);
return createUniqueAndNewJSON(lineGraphs, uniquePerDay, newPerDay, TimeUnit.DAYS.toMillis(1L));
}
public String hourlyUniqueAndNewGraphJSON() {
Database db = dbSystem.getDatabase();
LineGraphFactory lineGraphs = graphs.line();
long now = System.currentTimeMillis();
long weekAgo = now - TimeUnit.DAYS.toMillis(7L);
int timeZoneOffset = config.getTimeZone().getOffset(now);
NavigableMap<Long, Integer> uniquePerDay = db.query(
PlayerCountQueries.hourlyUniquePlayerCounts(weekAgo, now, timeZoneOffset)
);
NavigableMap<Long, Integer> newPerDay = db.query(
PlayerCountQueries.hourlyNewPlayerCounts(weekAgo, now, timeZoneOffset)
);
return createUniqueAndNewJSON(lineGraphs, uniquePerDay, newPerDay, TimeUnit.HOURS.toMillis(1L));
}
public String serverCalendarJSON(ServerUUID serverUUID) {
Database db = dbSystem.getDatabase();
long now = System.currentTimeMillis();
long twoYearsAgo = now - TimeUnit.DAYS.toMillis(730L);
int timeZoneOffset = config.getTimeZone().getOffset(now);
NavigableMap<Long, Integer> uniquePerDay = db.query(
PlayerCountQueries.uniquePlayerCounts(twoYearsAgo, now, timeZoneOffset, serverUUID)
);
NavigableMap<Long, Integer> newPerDay = db.query(
PlayerCountQueries.newPlayerCounts(twoYearsAgo, now, timeZoneOffset, serverUUID)
);
NavigableMap<Long, Long> playtimePerDay = db.query(
SessionQueries.playtimePerDay(twoYearsAgo, now, timeZoneOffset, serverUUID)
);
NavigableMap<Long, Integer> sessionsPerDay = db.query(
SessionQueries.sessionCountPerDay(twoYearsAgo, now, timeZoneOffset, serverUUID)
);
return "{\"data\":" +
graphs.calendar().serverCalendar(
uniquePerDay,
newPerDay,
playtimePerDay,
sessionsPerDay
).toCalendarSeries() +
",\"firstDay\":" + 1 + '}';
}
public String networkCalendarJSON() {
Database db = dbSystem.getDatabase();
long now = System.currentTimeMillis();
long twoYearsAgo = now - TimeUnit.DAYS.toMillis(730L);
int timeZoneOffset = config.getTimeZone().getOffset(now);
NavigableMap<Long, Integer> uniquePerDay = db.query(
PlayerCountQueries.uniquePlayerCounts(twoYearsAgo, now, timeZoneOffset)
);
NavigableMap<Long, Integer> newPerDay = db.query(
PlayerCountQueries.newPlayerCounts(twoYearsAgo, now, timeZoneOffset)
);
NavigableMap<Long, Long> playtimePerDay = db.query(
SessionQueries.playtimePerDay(twoYearsAgo, now, timeZoneOffset)
);
NavigableMap<Long, Integer> sessionsPerDay = db.query(
SessionQueries.sessionCountPerDay(twoYearsAgo, now, timeZoneOffset)
);
return "{\"data\":" +
graphs.calendar().serverCalendar(
uniquePerDay,
newPerDay,
playtimePerDay,
sessionsPerDay
).toCalendarSeries() +
",\"firstDay\":" + 1 + '}';
}
public Map<String, Object> serverWorldPieJSONAsMap(ServerUUID serverUUID) {
Database db = dbSystem.getDatabase();
WorldTimes worldTimes = db.query(WorldTimesQueries.fetchServerTotalWorldTimes(serverUUID));
WorldPie worldPie = graphs.pie().worldPie(worldTimes);
return Maps.builder(String.class, Object.class)
.put("world_series", worldPie.getSlices())
.put("gm_series", worldPie.toHighChartsDrillDownMaps())
.build();
}
public Map<String, Object> activityGraphsJSONAsMap(ServerUUID serverUUID) {
Database db = dbSystem.getDatabase();
long date = System.currentTimeMillis();
Long threshold = config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD);
DateMap<Map<String, Integer>> activityData = new DateMap<>();
for (long time = date; time >= date - TimeAmount.MONTH.toMillis(2L); time -= TimeAmount.WEEK.toMillis(1L)) {
activityData.put(time, db.query(ActivityIndexQueries.fetchActivityIndexGroupingsOn(time, serverUUID, threshold)));
}
return createActivityGraphJSON(activityData);
}
public Map<String, Object> createActivityGraphJSON(DateMap<Map<String, Integer>> activityData) {
Map.Entry<Long, Map<String, Integer>> lastActivityEntry = activityData.lastEntry();
Pie activityPie = graphs.pie().activityPie(lastActivityEntry != null ? lastActivityEntry.getValue() : Collections.emptyMap());
StackGraph activityStackGraph = graphs.stack().activityStackGraph(activityData);
return Maps.builder(String.class, Object.class)
.put("activity_series", activityStackGraph.getDataSets())
.put("activity_labels", activityStackGraph.getLabels())
.put("activity_pie_series", activityPie.getSlices())
.build();
}
public Map<String, Object> activityGraphsJSONAsMap() {
Database db = dbSystem.getDatabase();
long date = System.currentTimeMillis();
Long threshold = config.get(TimeSettings.ACTIVE_PLAY_THRESHOLD);
DateMap<Map<String, Integer>> activityData = new DateMap<>();
for (long time = date; time >= date - TimeAmount.MONTH.toMillis(2L); time -= TimeAmount.WEEK.toMillis(1L)) {
activityData.put(time, db.query(NetworkActivityIndexQueries.fetchActivityIndexGroupingsOn(time, threshold)));
}
return createActivityGraphJSON(activityData);
}
public Map<String, Object> geolocationGraphsJSONAsMap(ServerUUID serverUUID) {
Database db = dbSystem.getDatabase();
Map<String, Integer> geolocationCounts = db.query(GeoInfoQueries.serverGeolocationCounts(serverUUID));
return createGeolocationJSON(geolocationCounts);
}
public Map<String, Object> createGeolocationJSON(Map<String, Integer> geolocationCounts) {
BarGraph geolocationBarGraph = graphs.bar().geolocationBarGraph(geolocationCounts);
WorldMap worldMap = graphs.special().worldMap(geolocationCounts);
return Maps.builder(String.class, Object.class)
.put("geolocations_enabled", config.get(DataGatheringSettings.GEOLOCATIONS) && config.get(DataGatheringSettings.ACCEPT_GEOLITE2_EULA))
.put("geolocation_series", worldMap.getEntries())
.put("geolocation_bar_series", geolocationBarGraph.getBars())
.put("colors", Maps.builder(String.class, String.class)
.put("low", theme.getValue(ThemeVal.WORLD_MAP_LOW))
.put("high", theme.getValue(ThemeVal.WORLD_MAP_HIGH))
.put("bars", theme.getValue(ThemeVal.GREEN))
.build())
.build();
}
public Map<String, Object> geolocationGraphsJSONAsMap() {
Database db = dbSystem.getDatabase();
Map<String, Integer> geolocationCounts = db.query(GeoInfoQueries.networkGeolocationCounts());
return createGeolocationJSON(geolocationCounts);
}
public String pingGraphsJSON(ServerUUID serverUUID) {
Database db = dbSystem.getDatabase();
long now = System.currentTimeMillis();
List<Ping> pings = db.query(PingQueries.fetchPingDataOfServer(now - TimeUnit.DAYS.toMillis(180L), now, serverUUID));
PingGraph pingGraph = graphs.line().pingGraph(new PingMutator(pings).mutateToByMinutePings().all());
return "{\"min_ping_series\":" + pingGraph.getMinGraph().toHighChartsSeries() +
",\"avg_ping_series\":" + pingGraph.getAvgGraph().toHighChartsSeries() +
",\"max_ping_series\":" + pingGraph.getMaxGraph().toHighChartsSeries() +
",\"colors\":{" +
"\"min\":\"" + theme.getValue(ThemeVal.GRAPH_MIN_PING) + "\"," +
"\"avg\":\"" + theme.getValue(ThemeVal.GRAPH_AVG_PING) + "\"," +
"\"max\":\"" + theme.getValue(ThemeVal.GRAPH_MAX_PING) + "\"" +
"}}";
}
public Map<String, Object> punchCardJSONAsMap(ServerUUID serverUUID) {
long now = System.currentTimeMillis();
long monthAgo = now - TimeUnit.DAYS.toMillis(30L);
List<FinishedSession> sessions = dbSystem.getDatabase().query(
SessionQueries.fetchServerSessionsWithoutKillOrWorldData(monthAgo, now, serverUUID)
);
return Maps.builder(String.class, Object.class)
.put("punchCard", graphs.special().punchCard(sessions).getDots())
.put("color", theme.getValue(ThemeVal.GRAPH_PUNCHCARD))
.build();
}
public Map<String, Object> serverPreferencePieJSONAsMap() {
long now = System.currentTimeMillis();
long monthAgo = now - TimeUnit.DAYS.toMillis(30L);
String[] pieColors = theme.getPieColors(ThemeVal.GRAPH_WORLD_PIE);
Map<String, Long> playtimePerServer = dbSystem.getDatabase().query(SessionQueries.playtimePerServer(monthAgo, now));
return Maps.builder(String.class, Object.class)
.put("server_pie_colors", pieColors)
.put("server_pie_series_30d", graphs.pie().serverPreferencePie(playtimePerServer).getSlices())
.build();
}
public Map<String, Object> playerHostnamePieJSONAsMap() {
String[] pieColors = theme.getPieColors(ThemeVal.GRAPH_WORLD_PIE);
Map<String, Integer> joinAddresses = dbSystem.getDatabase().query(JoinAddressQueries.latestJoinAddresses());
translateUnknown(joinAddresses);
List<PieSlice> slices = graphs.pie().joinAddressPie(joinAddresses).getSlices();
slices.sort(new PieSliceComparator());
return Maps.builder(String.class, Object.class)
.put("colors", pieColors)
.put("slices", slices)
.build();
}
public Map<String, Object> playerHostnamePieJSONAsMap(ServerUUID serverUUID) {
String[] pieColors = theme.getPieColors(ThemeVal.GRAPH_WORLD_PIE);
Map<String, Integer> joinAddresses = dbSystem.getDatabase().query(JoinAddressQueries.latestJoinAddresses(serverUUID));
translateUnknown(joinAddresses);
List<PieSlice> slices = graphs.pie().joinAddressPie(joinAddresses).getSlices();
slices.sort(new PieSliceComparator());
return Maps.builder(String.class, Object.class)
.put("colors", pieColors)
.put("slices", slices)
.build();
}
public void translateUnknown(Map<String, Integer> joinAddresses) {
Integer unknown = joinAddresses.get(JoinAddressTable.DEFAULT_VALUE_FOR_LOOKUP);
if (unknown != null) {
joinAddresses.remove(JoinAddressTable.DEFAULT_VALUE_FOR_LOOKUP);
joinAddresses.put(GenericLang.UNKNOWN.getKey(), unknown);
}
}
public Map<String, Object> joinAddressesByDay(ServerUUID serverUUID, long after, long before) {
String[] pieColors = theme.getPieColors(ThemeVal.GRAPH_WORLD_PIE);
List<DateObj<Map<String, Integer>>> joinAddresses = dbSystem.getDatabase().query(JoinAddressQueries.joinAddressesPerDay(serverUUID, config.getTimeZone().getOffset(System.currentTimeMillis()), after, before));
return mapToJson(pieColors, joinAddresses);
}
public Map<String, Object> joinAddressesByDay(long after, long before) {
String[] pieColors = theme.getPieColors(ThemeVal.GRAPH_WORLD_PIE);
List<DateObj<Map<String, Integer>>> joinAddresses = dbSystem.getDatabase().query(JoinAddressQueries.joinAddressesPerDay(config.getTimeZone().getOffset(System.currentTimeMillis()), after, before));
return mapToJson(pieColors, joinAddresses);
}
private Map<String, Object> mapToJson(String[] pieColors, List<DateObj<Map<String, Integer>>> joinAddresses) {
for (DateObj<Map<String, Integer>> addressesByDate : joinAddresses) {
translateUnknown(addressesByDate.getValue());
}
List<JoinAddressCounts> joinAddressCounts = joinAddresses.stream()
.map(addressesOnDay -> new JoinAddressCounts(
addressesOnDay.getDate(),
addressesOnDay.getValue().entrySet()
.stream()
.map(JoinAddressCount::new)
.sorted()
.collect(Collectors.toList())))
.sorted(new DateHolderOldestComparator())
.collect(Collectors.toList());
return Maps.builder(String.class, Object.class)
.put("colors", pieColors)
.put("join_addresses_by_date", joinAddressCounts)
.build();
}
public GraphCollection<ServerSpecificLineGraph> proxyPlayersOnlineGraphs() {
Database db = dbSystem.getDatabase();
long now = System.currentTimeMillis();
long halfYearAgo = now - TimeUnit.DAYS.toMillis(180L);
List<ServerSpecificLineGraph> proxyGraphs = new ArrayList<>();
for (Server proxy : db.query(ServerQueries.fetchProxyServers())) {
ServerUUID proxyUUID = proxy.getUuid();
List<Number[]> points = Lists.map(
db.query(TPSQueries.fetchPlayersOnlineOfServer(halfYearAgo, now, proxyUUID)),
point -> Point.fromDateObj(point).toArray()
);
proxyGraphs.add(new ServerSpecificLineGraph(points, ServerDto.fromServer(proxy)));
}
return new GraphCollection<>(proxyGraphs, theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE));
}
}