diff --git a/Plan/src/main/java/com/djrapitops/plan/data/analysis/ActivityPart.java b/Plan/src/main/java/com/djrapitops/plan/data/analysis/ActivityPart.java index fc5afe461..4fc996fe0 100644 --- a/Plan/src/main/java/com/djrapitops/plan/data/analysis/ActivityPart.java +++ b/Plan/src/main/java/com/djrapitops/plan/data/analysis/ActivityPart.java @@ -91,6 +91,8 @@ public class ActivityPart extends RawData { addValue("datascatterweek", weekScatter); addValue("datascattermonth", monthScatter); + addValue("playersonlineseries", PlayerActivityGraphCreator.buildSeriesDataString(tpsData)); + addValue("%playersgraphcolor%", Settings.HCOLOR_ACT_ONL + ""); addValue("%playersgraphfill%", Settings.HCOLOR_ACT_ONL_FILL + ""); } diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/html/graphs/PlayerActivityGraphCreator.java b/Plan/src/main/java/com/djrapitops/plan/ui/html/graphs/PlayerActivityGraphCreator.java index cf018cb19..618ce7b9f 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ui/html/graphs/PlayerActivityGraphCreator.java +++ b/Plan/src/main/java/com/djrapitops/plan/ui/html/graphs/PlayerActivityGraphCreator.java @@ -22,6 +22,13 @@ public class PlayerActivityGraphCreator { throw new IllegalStateException("Utility class"); } + public static String buildSeriesDataString(List tpsData) { + List points = tpsData.stream() + .map(tps -> new Point(tps.getDate(), tps.getPlayers())) + .collect(Collectors.toList()); + return SeriesCreator.seriesGraph(points, true); + } + public static String buildScatterDataString(List tpsData, long scale) { long now = MiscUtils.getTime(); List points = tpsData.stream() diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/html/graphs/SeriesCreator.java b/Plan/src/main/java/com/djrapitops/plan/ui/html/graphs/SeriesCreator.java new file mode 100644 index 000000000..7b103efdb --- /dev/null +++ b/Plan/src/main/java/com/djrapitops/plan/ui/html/graphs/SeriesCreator.java @@ -0,0 +1,80 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package main.java.com.djrapitops.plan.ui.html.graphs; + +import com.djrapitops.plugin.api.TimeAmount; +import com.djrapitops.plugin.utilities.Verify; +import main.java.com.djrapitops.plan.utilities.analysis.DouglasPeuckerAlgorithm; +import main.java.com.djrapitops.plan.utilities.analysis.Point; +import main.java.com.djrapitops.plan.utilities.comparators.PointComparator; + +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Abstract scatter graph creator used by other graph creators. + * + * @author Rsl1122 + * @since 3.5.2 + */ +public class SeriesCreator { + + /** + * Constructor used to hide the public constructor + */ + private SeriesCreator() { + throw new IllegalStateException("Utility class"); + } + + public static String seriesGraph(List points, boolean reduceGapTriangles) { + return seriesGraph(points, reduceGapTriangles, true); + } + + public static String seriesGraph(List points, boolean reduceGapTriangles, boolean reducePoints) { + StringBuilder arrayBuilder = new StringBuilder("["); + + if (reducePoints) { + points = DouglasPeuckerAlgorithm.reducePoints(points, 0); + } + + if (reduceGapTriangles) { + Point lastPoint = null; + + Set toAdd = new HashSet<>(); + for (Point point : points) { + if (Verify.notNull(point, lastPoint)) { + long date = (long) point.getX(); + long lastDate = (long) lastPoint.getX(); + double y = point.getY(); + double lastY = lastPoint.getY(); + if (Double.compare(y, lastY) != 0 && Math.abs(lastY - y) > 0.5) { + if (lastDate < date - TimeAmount.MINUTE.ms() * 10L) { + toAdd.add(new Point(lastDate + 1, lastY)); + toAdd.add(new Point(date - 1, lastY)); + } + } + } + lastPoint = point; + } + points.addAll(toAdd); + points.sort(new PointComparator()); + } + + int size = points.size(); + for (int i = 0; i < size; i++) { + Point point = points.get(i); + double y = point.getY(); + long date = (long) point.getX(); + arrayBuilder.append("[").append(date).append(",").append(y).append("]"); + if (i < size - 1) { + arrayBuilder.append(","); + } + } + arrayBuilder.append("]"); + return arrayBuilder.toString(); + } +} diff --git a/Plan/src/main/java/com/djrapitops/plan/ui/webserver/WebServer.java b/Plan/src/main/java/com/djrapitops/plan/ui/webserver/WebServer.java index 91ac2e451..b79673377 100644 --- a/Plan/src/main/java/com/djrapitops/plan/ui/webserver/WebServer.java +++ b/Plan/src/main/java/com/djrapitops/plan/ui/webserver/WebServer.java @@ -80,14 +80,15 @@ public class WebServer { try { URI uri = exchange.getRequestURI(); String target = uri.toString(); - + Headers responseHeaders = exchange.getResponseHeaders(); + responseHeaders.set("Content-Type", "text/html;"); WebUser user = null; if (usingHttps) { user = getUser(exchange.getRequestHeaders()); // Prompt authorization if (user == null) { - Headers responseHeaders = exchange.getResponseHeaders(); + responseHeaders.set("WWW-Authenticate", "Basic realm=\"/\";"); } } diff --git a/Plan/src/main/resources/analysis.html b/Plan/src/main/resources/analysis.html index ee4098107..0e0fa6e64 100644 --- a/Plan/src/main/resources/analysis.html +++ b/Plan/src/main/resources/analysis.html @@ -342,7 +342,8 @@ - + +

Unique Players: %uniquejoinsday% | Unique/Day: %avguniquejoinsday%

@@ -723,12 +724,54 @@ - + + +