diff --git a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java index 646aca24d..f0ac5f37c 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/db/access/queries/objects/SessionQueries.java @@ -717,4 +717,31 @@ public class SessionQueries { } }; } + + public static Query> playtimePerServer(long after, long before) { + String sql = SELECT + + "SUM(" + SessionsTable.SESSION_END + '-' + SessionsTable.SESSION_START + ") as playtime," + + ServerTable.NAME + + FROM + SessionsTable.TABLE_NAME + + INNER_JOIN + ServerTable.TABLE_NAME + " s on s." + ServerTable.SERVER_UUID + '=' + SessionsTable.TABLE_NAME + '.' + SessionsTable.SERVER_UUID + + WHERE + SessionsTable.SESSION_END + ">=?" + + AND + SessionsTable.SESSION_START + "<=?" + + GROUP_BY + ServerTable.NAME; + return new QueryStatement>(sql, 100) { + @Override + public void prepare(PreparedStatement statement) throws SQLException { + statement.setLong(1, after); + statement.setLong(2, before); + } + + @Override + public Map processResults(ResultSet set) throws SQLException { + Map playtimePerServer = new HashMap<>(); + while (set.next()) { + playtimePerServer.put(set.getString(ServerTable.NAME), set.getLong("playtime")); + } + return playtimePerServer; + } + }; + } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/json/GraphJSONParser.java b/Plan/common/src/main/java/com/djrapitops/plan/system/json/GraphJSONParser.java index bec699728..3a8cf4a6b 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/json/GraphJSONParser.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/json/GraphJSONParser.java @@ -31,6 +31,8 @@ import com.djrapitops.plan.db.access.queries.objects.*; import com.djrapitops.plan.system.database.DBSystem; import com.djrapitops.plan.system.settings.config.PlanConfig; import com.djrapitops.plan.system.settings.paths.TimeSettings; +import com.djrapitops.plan.system.settings.theme.Theme; +import com.djrapitops.plan.system.settings.theme.ThemeVal; import com.djrapitops.plan.utilities.html.graphs.Graphs; import com.djrapitops.plan.utilities.html.graphs.bar.BarGraph; import com.djrapitops.plan.utilities.html.graphs.line.LineGraphFactory; @@ -57,6 +59,7 @@ import java.util.stream.Collectors; public class GraphJSONParser { private final PlanConfig config; + private final Theme theme; private final DBSystem dbSystem; private final Graphs graphs; private final TimeZone timeZone; @@ -64,10 +67,12 @@ public class GraphJSONParser { @Inject public GraphJSONParser( PlanConfig config, + Theme theme, DBSystem dbSystem, Graphs graphs ) { this.config = config; + this.theme = theme; this.dbSystem = dbSystem; this.graphs = graphs; this.timeZone = config.getTimeZone(); @@ -264,4 +269,18 @@ public class GraphJSONParser { ); return Collections.singletonMap("punchCard", graphs.special().punchCard(sessions).getDots()); } + + public Map serverPreferencePieJSONAsMap() { + long now = System.currentTimeMillis(); + long monthAgo = now - TimeUnit.DAYS.toMillis(30L); + String[] pieColors = Arrays.stream(theme.getValue(ThemeVal.GRAPH_WORLD_PIE).split(",")) + .map(color -> color.trim().replace("\"", "")) + .toArray(String[]::new); + Map data = new HashMap<>(); + data.put("server_pie_colors", pieColors); + + Map serverPlaytimes = dbSystem.getDatabase().query(SessionQueries.playtimePerServer(now, monthAgo)); + data.put("server_pie_series_30d", graphs.pie().serverPreferencePie(serverPlaytimes).getSlices()); + return data; + } } \ No newline at end of file diff --git a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/GraphsJSONHandler.java b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/GraphsJSONHandler.java index eb33e7c28..74e20af2f 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/GraphsJSONHandler.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/system/webserver/pages/json/GraphsJSONHandler.java @@ -96,6 +96,8 @@ public class GraphsJSONHandler implements PageHandler { return new JSONResponse(graphJSON.activityGraphsJSONAsMap()); case "uniqueAndNew": return new JSONResponse(graphJSON.uniqueAndNewGraphJSON()); + case "serverPie": + return new JSONResponse(graphJSON.serverPreferencePieJSONAsMap()); default: throw new BadRequestException("unknown 'type' parameter: " + type); } diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieGraphFactory.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieGraphFactory.java index 03eb454d0..823669dc5 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieGraphFactory.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/PieGraphFactory.java @@ -65,11 +65,14 @@ public class PieGraphFactory { return new ActivityPie(activityData, colors); } - public Pie serverPreferencePie(Map serverNames, Map serverWorldTimes) { return new ServerPreferencePie(serverNames, serverWorldTimes); } + public Pie serverPreferencePie(Map serverPlaytimes) { + return new ServerPreferencePie(serverPlaytimes); + } + public WorldPie worldPie(WorldTimes worldTimes) { WorldAliasSettings worldAliasSettings = config.getWorldAliasSettings(); Map playtimePerAlias = worldAliasSettings.getPlaytimePerAlias(worldTimes); diff --git a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ServerPreferencePie.java b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ServerPreferencePie.java index e16a770c0..293f2be10 100644 --- a/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ServerPreferencePie.java +++ b/Plan/common/src/main/java/com/djrapitops/plan/utilities/html/graphs/pie/ServerPreferencePie.java @@ -29,6 +29,10 @@ public class ServerPreferencePie extends Pie { super(turnToSlices(serverNames, serverWorldTimes)); } + ServerPreferencePie(Map serverPlaytimes) { + super(turnToSlices(serverPlaytimes)); + } + private static List turnToSlices(Map serverNames, Map serverWorldTimes) { List slices = new ArrayList<>(); @@ -44,4 +48,16 @@ public class ServerPreferencePie extends Pie { return slices; } + + private static List turnToSlices(Map serverPlaytimes) { + List slices = new ArrayList<>(); + + for (Map.Entry server : serverPlaytimes.entrySet()) { + String serverName = server.getKey(); + long playtime = server.getValue(); + slices.add(new PieSlice(serverName, playtime)); + } + + return slices; + } } diff --git a/Plan/common/src/main/resources/assets/plan/web/network.html b/Plan/common/src/main/resources/assets/plan/web/network.html index a35ea23c9..0a4553912 100644 --- a/Plan/common/src/main/resources/assets/plan/web/network.html +++ b/Plan/common/src/main/resources/assets/plan/web/network.html @@ -404,7 +404,7 @@
- Server Playtime
+ Server Playtime for 30 Days
@@ -944,6 +944,20 @@ } }); + jsonRequest("../v1/graph?type=serverPie", function (json, error) { + if (data) { + serverPieSeries = { + name: 'Server Playtime', + colorByPoint: true, + colors: json.server_pie_colors, + data: json.server_pie_series_30d + }; + serverPie('serverPie', serverPieSeries); + } else if (error) { + $('#serverPie').text("Failed to load graph data: " + error) + } + }); + jsonRequest("../v1/graph?type=activity", function (json, error) { if (json) { activityPie('activityPie', {