mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-12-28 03:57:33 +01:00
Refactored Graphs to be Objects. Sensible after "Creator" name removal.
This commit is contained in:
parent
34198543ff
commit
a22aa95c22
@ -1,97 +0,0 @@
|
||||
package com.djrapitops.plan;
|
||||
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import net.md_5.bungee.api.ProxyServer;
|
||||
import org.bukkit.Server;
|
||||
|
||||
/**
|
||||
* Class responsible for holding server variable values that do not change
|
||||
* without a reload.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 3.4.1
|
||||
*/
|
||||
public class ServerVariableHolder {
|
||||
|
||||
private final String name;
|
||||
private final int port;
|
||||
private final String version;
|
||||
private final String implVersion;
|
||||
private final String ip;
|
||||
private final int maxPlayers;
|
||||
private final boolean usingPaper;
|
||||
|
||||
/**
|
||||
* Constructor, grabs the variables.
|
||||
*
|
||||
* @param server instance the plugin is running on.
|
||||
*/
|
||||
public ServerVariableHolder(Server server) {
|
||||
ip = server.getIp();
|
||||
name = server.getName();
|
||||
port = server.getPort();
|
||||
version = server.getVersion();
|
||||
implVersion = server.getBukkitVersion();
|
||||
|
||||
maxPlayers = server.getMaxPlayers();
|
||||
|
||||
usingPaper = name.equals("Paper")
|
||||
|| name.equals("TacoSpigot"); //Fork of Paper
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor, grabs the variables.
|
||||
*
|
||||
* @param server instance the plugin is running on.
|
||||
*/
|
||||
public ServerVariableHolder(ProxyServer server) {
|
||||
ip = Settings.BUNGEE_IP.toString();
|
||||
name = "BungeeCord";
|
||||
port = -1;
|
||||
version = server.getVersion();
|
||||
implVersion = server.getVersion();
|
||||
|
||||
maxPlayers = server.getConfig().getPlayerLimit();
|
||||
|
||||
usingPaper = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ip string in server.properties.
|
||||
*
|
||||
* @return the ip.
|
||||
*/
|
||||
public String getIp() {
|
||||
return ip;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if the server is using PaperSpigot.
|
||||
*
|
||||
* @return if the server is using PaperSpigot.
|
||||
*/
|
||||
@Deprecated
|
||||
public boolean isUsingPaper() {
|
||||
return usingPaper;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public String getImplVersion() {
|
||||
return implVersion;
|
||||
}
|
||||
|
||||
public int getMaxPlayers() {
|
||||
return maxPlayers;
|
||||
}
|
||||
}
|
@ -144,11 +144,11 @@ public class AnalysisData extends RawData {
|
||||
|
||||
Map<String, Set<UUID>> activityNow = activityData.getOrDefault(now, new HashMap<>());
|
||||
|
||||
String[] activityStackSeries = ActivityStackGraph.createSeries(activityData);
|
||||
String activityPieSeries = ActivityPie.createSeries(activityNow);
|
||||
ActivityStackGraph activityStackGraph = new ActivityStackGraph(activityData);
|
||||
String activityPieSeries = new ActivityPie(activityNow).toHighChartsSeries();
|
||||
|
||||
addValue("activityStackCategories", activityStackSeries[0]);
|
||||
addValue("activityStackSeries", activityStackSeries[1]);
|
||||
addValue("activityStackCategories", activityStackGraph.toHighChartsLabels());
|
||||
addValue("activityStackSeries", activityStackGraph.toHighChartsSeries());
|
||||
addValue("activityPieSeries", activityPieSeries);
|
||||
|
||||
Set<UUID> veryActiveNow = activityNow.getOrDefault("Very Active", new HashSet<>());
|
||||
@ -171,7 +171,7 @@ public class AnalysisData extends RawData {
|
||||
}
|
||||
|
||||
private void geolocationsTab(List<String> geoLocations) {
|
||||
addValue("geoMapSeries", WorldMap.createSeries(geoLocations));
|
||||
addValue("geoMapSeries", new WorldMap(geoLocations).toHighChartsSeries());
|
||||
}
|
||||
|
||||
private void onlineActivityNumbers(ServerProfile profile, Map<UUID, List<Session>> sessions, List<PlayerProfile> players) {
|
||||
@ -286,7 +286,7 @@ public class AnalysisData extends RawData {
|
||||
addValue("tableBodySessions", tables[0]);
|
||||
addValue("listRecentLogins", tables[1]);
|
||||
addValue("sessionAverage", FormatUtils.formatTimeAmount(MathUtils.averageLong(allSessions.stream().map(Session::getLength))));
|
||||
addValue("punchCardSeries", PunchCardGraph.createSeries(sessionsMonth));
|
||||
addValue("punchCardSeries", new PunchCardGraph(sessionsMonth).toHighChartsSeries());
|
||||
|
||||
addValue("deaths", ServerProfile.getDeathCount(allSessions));
|
||||
addValue("mobKillCount", ServerProfile.getMobKillCount(allSessions));
|
||||
@ -303,9 +303,9 @@ public class AnalysisData extends RawData {
|
||||
Html.TABLE_PLAYERS_FOOTER.parse(playersTableBody)
|
||||
: Html.TABLE_PLAYERS.parse(playersTableBody));
|
||||
addValue("worldTotal", FormatUtils.formatTimeAmount(worldTimes.getTotal()));
|
||||
String[] seriesData = WorldPie.createSeries(worldTimes);
|
||||
addValue("worldSeries", seriesData[0]);
|
||||
addValue("gmSeries", seriesData[1]);
|
||||
WorldPie worldPie = new WorldPie(worldTimes);
|
||||
addValue("worldSeries", worldPie.toHighChartsSeries());
|
||||
addValue("gmSeries", worldPie.toHighChartsDrilldown());
|
||||
addValue("lastPeakTime", lastPeak != -1 ? FormatUtils.formatTimeStampYear(lastPeak) : "No Data");
|
||||
addValue("playersLastPeak", lastPeak != -1 ? profile.getLastPeakPlayers() : "-");
|
||||
addValue("bestPeakTime", allTimePeak != -1 ? FormatUtils.formatTimeStampYear(allTimePeak) : "No Data");
|
||||
@ -320,12 +320,12 @@ public class AnalysisData extends RawData {
|
||||
addValue("tpsSpikeWeek", value("tpsSpikeWeek"));
|
||||
addValue("tpsSpikeDay", value("tpsSpikeDay"));
|
||||
|
||||
addValue("playersOnlineSeries", PlayerActivityGraph.createSeries(tpsData));
|
||||
addValue("tpsSeries", TPSGraph.createSeries(tpsData));
|
||||
addValue("cpuSeries", CPUGraph.createSeries(tpsData));
|
||||
addValue("ramSeries", RamGraph.createSeries(tpsData));
|
||||
addValue("entitySeries", WorldLoadGraph.createSeriesEntities(tpsData));
|
||||
addValue("chunkSeries", WorldLoadGraph.createSeriesChunks(tpsData));
|
||||
addValue("playersOnlineSeries", new OnlineActivityGraph(tpsData).toHighChartsSeries());
|
||||
addValue("tpsSeries", new TPSGraph(tpsData).toHighChartsSeries());
|
||||
addValue("cpuSeries", new CPUGraph(tpsData).toHighChartsSeries());
|
||||
addValue("ramSeries", new RamGraph(tpsData).toHighChartsSeries());
|
||||
addValue("entitySeries", new EntityGraph(tpsData).toHighChartsSeries());
|
||||
addValue("chunkSeries", new ChunkGraph(tpsData).toHighChartsSeries());
|
||||
|
||||
double averageCPUMonth = MathUtils.averageDouble(tpsDataMonth.stream().map(TPS::getCPUUsage).filter(i -> i != 0));
|
||||
double averageCPUWeek = MathUtils.averageDouble(tpsDataWeek.stream().map(TPS::getCPUUsage).filter(i -> i != 0));
|
||||
|
@ -21,6 +21,10 @@ public class ActivityIndex {
|
||||
return value < 0 ? 1 : value;
|
||||
}
|
||||
|
||||
public static String[] getGroups() {
|
||||
return new String[]{"Very Active", "Active", "Regular", "Irregular", "Inactive"};
|
||||
}
|
||||
|
||||
private double calculate(PlayerProfile player, long date) {
|
||||
long week = TimeAmount.WEEK.ms();
|
||||
long weekAgo = date - week;
|
||||
|
@ -27,7 +27,7 @@ import com.djrapitops.plan.utilities.file.FileUtil;
|
||||
import com.djrapitops.plan.utilities.html.HtmlStructure;
|
||||
import com.djrapitops.plan.utilities.html.HtmlUtils;
|
||||
import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph;
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.ServerPreferencePie;
|
||||
import com.djrapitops.plan.utilities.html.graphs.pie.ServerPreferencePie;
|
||||
import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie;
|
||||
import com.djrapitops.plan.utilities.html.structure.ServerAccordionCreator;
|
||||
import com.djrapitops.plan.utilities.html.tables.ActionsTableCreator;
|
||||
@ -110,7 +110,7 @@ public class InspectPage extends Page {
|
||||
}
|
||||
|
||||
Map<UUID, WorldTimes> worldTimesPerServer = profile.getWorldTimesPerServer();
|
||||
addValue("serverPieSeries", ServerPreferencePie.createSeries(serverNames, worldTimesPerServer));
|
||||
addValue("serverPieSeries", new ServerPreferencePie(serverNames, worldTimesPerServer).toHighChartsSeries());
|
||||
addValue("worldPieColors", Theme.getValue(ThemeVal.GRAPH_WORLD_PIE));
|
||||
addValue("gmPieColors", Theme.getValue(ThemeVal.GRAPH_GM_PIE));
|
||||
addValue("serverPieColors", Theme.getValue(ThemeVal.GRAPH_SERVER_PREF_PIE));
|
||||
@ -197,14 +197,14 @@ public class InspectPage extends Page {
|
||||
List<Action> actions = profile.getAllActions();
|
||||
addValue("tableBodyActions", ActionsTableCreator.createTable(actions));
|
||||
|
||||
String punchCardData = PunchCardGraph.createSeries(allSessions);
|
||||
String punchCardData = new PunchCardGraph(allSessions).toHighChartsSeries();
|
||||
WorldTimes worldTimes = profile.getWorldTimes();
|
||||
AnalysisUtils.addMissingWorlds(worldTimes);
|
||||
|
||||
String[] worldPieData = WorldPie.createSeries(worldTimes);
|
||||
WorldPie worldPie = new WorldPie(worldTimes);
|
||||
|
||||
addValue("worldPieSeries", worldPieData[0]);
|
||||
addValue("gmSeries", worldPieData[1]);
|
||||
addValue("worldPieSeries", worldPie.toHighChartsSeries());
|
||||
addValue("gmSeries", worldPie.toHighChartsDrilldown());
|
||||
|
||||
addValue("punchCardSeries", punchCardData);
|
||||
|
||||
|
@ -20,7 +20,7 @@ import com.djrapitops.plan.utilities.analysis.AnalysisUtils;
|
||||
import com.djrapitops.plan.utilities.file.FileUtil;
|
||||
import com.djrapitops.plan.utilities.html.HtmlStructure;
|
||||
import com.djrapitops.plan.utilities.html.HtmlUtils;
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.PlayerActivityGraph;
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.OnlineActivityGraph;
|
||||
import com.djrapitops.plugin.api.TimeAmount;
|
||||
|
||||
import java.util.List;
|
||||
@ -56,7 +56,7 @@ public class NetworkPage extends Page {
|
||||
addValue("timeZone", MiscUtils.getTimeZoneOffsetHours());
|
||||
addValue("networkName", Settings.BUNGEE_NETWORK_NAME.toString());
|
||||
addValue("version", plugin.getVersion());
|
||||
addValue("playersOnlineSeries", PlayerActivityGraph.createSeries(networkOnlineData));
|
||||
addValue("playersOnlineSeries", new OnlineActivityGraph(networkOnlineData).toHighChartsSeries());
|
||||
addValue("playersGraphColor", Theme.getValue(ThemeVal.GRAPH_PLAYERS_ONLINE));
|
||||
addValue("playersOnline", plugin.getProxy().getOnlineCount());
|
||||
|
||||
|
@ -13,7 +13,7 @@ import com.djrapitops.plan.system.info.server.ServerProperties;
|
||||
import com.djrapitops.plan.system.settings.Settings;
|
||||
import com.djrapitops.plan.systems.info.BukkitInformationManager;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.PlayerActivityGraph;
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.OnlineActivityGraph;
|
||||
import com.djrapitops.plan.utilities.html.structure.SessionTabStructureCreator;
|
||||
import com.djrapitops.plan.utilities.html.tables.SessionsTableCreator;
|
||||
import com.djrapitops.plugin.api.utility.log.Log;
|
||||
@ -108,7 +108,7 @@ public class HtmlStructure {
|
||||
}
|
||||
|
||||
public static String createServerContainer(Plan plugin) {
|
||||
ServerProperties variable = plugin.getVariable();
|
||||
ServerProperties variable = ServerInfo.getServerProperties();
|
||||
int maxPlayers = variable.getMaxPlayers();
|
||||
int online = plugin.getServer().getOnlinePlayers().size();
|
||||
Optional<Long> analysisRefreshDate = ((BukkitInformationManager) plugin.getInfoManager()).getAnalysisRefreshDate();
|
||||
@ -127,7 +127,7 @@ public class HtmlStructure {
|
||||
String playerData = "[]";
|
||||
try {
|
||||
playerCount = db.count().getServerPlayerCount(serverUUID);
|
||||
playerData = PlayerActivityGraph.createSeries(db.fetch().getTPSData(serverUUID));
|
||||
playerData = new OnlineActivityGraph(db.fetch().getTPSData(serverUUID)).toHighChartsSeries();
|
||||
} catch (DBException e) {
|
||||
Log.toLog(HtmlStructure.class.getClass().getName(), e);
|
||||
}
|
||||
|
@ -4,10 +4,10 @@
|
||||
*/
|
||||
package com.djrapitops.plan.utilities.html.graphs;
|
||||
|
||||
import com.djrapitops.plan.data.element.ActivityIndex;
|
||||
import com.djrapitops.plan.settings.theme.Theme;
|
||||
import com.djrapitops.plan.settings.theme.ThemeVal;
|
||||
import com.djrapitops.plan.utilities.FormatUtils;
|
||||
import com.djrapitops.plan.utilities.html.graphs.pie.ActivityPie;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
@ -15,30 +15,46 @@ import java.util.TreeMap;
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Graph creation utility for Activity Stack graph.
|
||||
*
|
||||
* This graph represents evolution of the playerbase.
|
||||
* Stack Graph that represents evolution of the PlayerBase in terms of ActivityIndex Groups.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see ActivityIndex
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class ActivityStackGraph {
|
||||
public class ActivityStackGraph implements HighChart {
|
||||
|
||||
private final String[] builtSeries;
|
||||
|
||||
public ActivityStackGraph(TreeMap<Long, Map<String, Set<UUID>>> activityData) {
|
||||
this.builtSeries = createSeries(activityData);
|
||||
}
|
||||
|
||||
public String toHighChartsLabels() {
|
||||
return builtSeries[0];
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toHighChartsSeries() {
|
||||
return builtSeries[1];
|
||||
}
|
||||
|
||||
private ActivityStackGraph() {
|
||||
throw new IllegalStateException("Utility Class");
|
||||
}
|
||||
|
||||
public static String[] createSeries(TreeMap<Long, Map<String, Set<UUID>>> activityData) {
|
||||
String[] sliceNames = ActivityPie.getSliceNames();
|
||||
private String[] createSeries(TreeMap<Long, Map<String, Set<UUID>>> activityData) {
|
||||
String[] groups = ActivityIndex.getGroups();
|
||||
String[] colors = Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE).split(", ");
|
||||
int maxCol = colors.length;
|
||||
|
||||
StringBuilder[] series = new StringBuilder[sliceNames.length + 1];
|
||||
for (int i = 0; i <= sliceNames.length; i++) {
|
||||
// Series 0 is Labels for Graph x-axis, others are data for each group.
|
||||
StringBuilder[] series = new StringBuilder[groups.length + 1];
|
||||
for (int i = 0; i <= groups.length; i++) {
|
||||
series[i] = new StringBuilder();
|
||||
}
|
||||
for (int i = 1; i <= sliceNames.length; i++) {
|
||||
for (int i = 1; i <= groups.length; i++) {
|
||||
series[i] = new StringBuilder("{name: '")
|
||||
.append(sliceNames[i - 1])
|
||||
.append(groups[i - 1])
|
||||
.append("',color:").append(colors[(i - 1) % maxCol])
|
||||
.append(",data: [");
|
||||
}
|
||||
@ -49,13 +65,13 @@ public class ActivityStackGraph {
|
||||
Map<String, Set<UUID>> data = activityData.get(date);
|
||||
|
||||
series[0].append("'").append(FormatUtils.formatTimeStamp(date)).append("'");
|
||||
for (int j = 1; j <= sliceNames.length; j++) {
|
||||
Set<UUID> players = data.get(sliceNames[j - 1]);
|
||||
for (int j = 1; j <= groups.length; j++) {
|
||||
Set<UUID> players = data.get(groups[j - 1]);
|
||||
series[j].append(players != null ? players.size() : 0);
|
||||
}
|
||||
|
||||
if (i < size - 1) {
|
||||
for (int j = 0; j <= sliceNames.length; j++) {
|
||||
for (int j = 0; j <= groups.length; j++) {
|
||||
series[j].append(",");
|
||||
}
|
||||
}
|
||||
@ -64,9 +80,9 @@ public class ActivityStackGraph {
|
||||
|
||||
StringBuilder seriesBuilder = new StringBuilder("[");
|
||||
|
||||
for (int j = 1; j <= sliceNames.length; j++) {
|
||||
for (int j = 1; j <= groups.length; j++) {
|
||||
seriesBuilder.append(series[j].append("]}").toString());
|
||||
if (j < sliceNames.length) {
|
||||
if (j < groups.length) {
|
||||
seriesBuilder.append(",");
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Licence is provided in the jar as license.yml also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
|
||||
*/
|
||||
package com.djrapitops.plan.utilities.html.graphs;
|
||||
|
||||
/**
|
||||
* Interface for Graphs with HighCharts data support.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public interface HighChart {
|
||||
|
||||
String toHighChartsSeries();
|
||||
|
||||
}
|
@ -14,27 +14,26 @@ import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Utility class for creating Punch Card Data Array for the JavaScripts.
|
||||
* Bubble Chart that represents login "punches" of players.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 3.6.0
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class PunchCardGraph {
|
||||
public class PunchCardGraph implements HighChart {
|
||||
|
||||
private final Collection<Session> sessions;
|
||||
|
||||
/**
|
||||
* Constructor used to hide the public constructor
|
||||
* Constuctor for the graph.
|
||||
*
|
||||
* @param sessions All sessions of All users this PunchCard represents.
|
||||
*/
|
||||
private PunchCardGraph() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
public PunchCardGraph(Collection<Session> sessions) {
|
||||
this.sessions = sessions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a PunchCard series data Array for HighCharts
|
||||
*
|
||||
* @param sessions Sessions (Unique/Player) to be placed into the PunchCard.
|
||||
* @return Data array as a string.
|
||||
*/
|
||||
public static String createSeries(Collection<Session> sessions) {
|
||||
@Override
|
||||
public String toHighChartsSeries() {
|
||||
List<Long> sessionStarts = getSessionStarts(sessions);
|
||||
List<int[]> daysAndHours = AnalysisUtils.getDaysAndHours(sessionStarts);
|
||||
int[][] dataArray = turnIntoArray(daysAndHours);
|
||||
|
@ -4,57 +4,24 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class WorldMap {
|
||||
/**
|
||||
* World Map that uses iso-a3 specification of Country codes.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class WorldMap implements HighChart {
|
||||
|
||||
/**
|
||||
* Constructor used to hide the public constructor
|
||||
*/
|
||||
private WorldMap() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
private final List<String> geoLocations;
|
||||
|
||||
/**
|
||||
* Creates a data series with iso-a3 specification of Country codes.
|
||||
*
|
||||
* @param geoLocations The country names of players
|
||||
* @return The created data series
|
||||
*/
|
||||
public static String createSeries(List<String> geoLocations) {
|
||||
|
||||
Map<String, Integer> geoCodeCounts = new HashMap<>();
|
||||
Map<String, String> geoCodes = getGeoCodes(geoCodeCounts);
|
||||
|
||||
for (String geoLocation : geoLocations) {
|
||||
String countryCode = geoCodes.get(geoLocation);
|
||||
if (countryCode != null) {
|
||||
geoCodeCounts.computeIfPresent(countryCode, (computedCountry, amount) -> amount + 1);
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder arrayBuilder = new StringBuilder("[");
|
||||
|
||||
int i = 0;
|
||||
int size = geoCodeCounts.size();
|
||||
for (Map.Entry<String, Integer> entry : geoCodeCounts.entrySet()) {
|
||||
String geoCode = entry.getKey();
|
||||
Integer players = entry.getValue();
|
||||
|
||||
if (players != 0) {
|
||||
arrayBuilder.append("{'code':'").append(geoCode).append("','value':").append(players).append("}");
|
||||
if (i < size - 1) {
|
||||
arrayBuilder.append(",");
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
arrayBuilder.append("]");
|
||||
return arrayBuilder.toString();
|
||||
public WorldMap(List<String> geoLocations) {
|
||||
this.geoLocations = geoLocations;
|
||||
}
|
||||
|
||||
private static Map<String, String> getGeoCodes(Map<String, Integer> geoCodeCounts) {
|
||||
Map<String, String> geoCodes = new HashMap<>();
|
||||
// Countries & Codes have been copied from a iso-a3 specification file.
|
||||
// Each index corresponds to each code.
|
||||
String[] countries = new String[]{"Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra", "Angola", "Anguilla", "Antigua and Barbuda", "Argentina", "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan", "Bahamas, The", "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium", "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia", "Bosnia and Herzegovina", "Botswana", "Brazil", "British Virgin Islands", "Brunei", "Bulgaria", "Burkina Faso", "Burma", "Burundi", "Cabo Verde", "Cambodia", "Cameroon", "Canada", "Cayman Islands", "Central African Republic", "Chad", "Chile", "China", "Colombia", "Comoros", "Congo, Democratic Republic of the", "Congo, Republic of the", "Cook Islands", "Costa Rica", "Cote d'Ivoire", "Croatia", "Cuba", "Curacao", "Cyprus", "Czech Republic", "Denmark", "Djibouti", "Dominica", "Dominican Republic", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea", "Estonia", "Ethiopia", "Falkland Islands (Islas Malvinas)", "Faroe Islands", "Fiji", "Finland", "France", "French Polynesia", "Gabon", "Gambia, The", "Georgia", "Germany", "Ghana", "Gibraltar", "Greece", "Greenland", "Grenada", "Guam", "Guatemala", "Guernsey", "Guinea-Bissau", "Guinea", "Guyana", "Haiti", "Honduras", "Hong Kong", "Hungary", "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Isle of Man", "Israel", "Italy", "Jamaica", "Japan", "Jersey", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Korea, North", "Korea, South", "Kosovo", "Kuwait", "Kyrgyzstan", "Laos", "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg", "Macau", "Macedonia", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands", "Mauritania", "Mauritius", "Mexico", "Micronesia, Federated States of", "Moldova", "Monaco", "Mongolia", "Montenegro", "Morocco", "Mozambique", "Namibia", "Nepal", "Netherlands", "New Caledonia", "New Zealand", "Nicaragua", "Nigeria", "Niger", "Niue", "Northern Mariana Islands", "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru", "Philippines", "Poland", "Portugal", "Puerto Rico", "Qatar", "Romania", "Russia", "Rwanda", "Saint Kitts and Nevis", "Saint Lucia", "Saint Martin", "Saint Pierre and Miquelon", "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Sao Tome and Principe", "Saudi Arabia", "Senegal", "Serbia", "Seychelles", "Sierra Leone", "Singapore", "Sint Maarten", "Slovakia", "Slovenia", "Solomon Islands", "Somalia", "South Africa", "South Sudan", "Spain", "Sri Lanka", "Sudan", "Suriname", "Swaziland", "Sweden", "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "Timor-Leste", "Togo", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey", "Turkmenistan", "Tuvalu", "Uganda", "Ukraine", "United Arab Emirates", "United Kingdom", "United States", "Uruguay", "Uzbekistan", "Vanuatu", "Venezuela", "Vietnam", "Virgin Islands", "West Bank", "Yemen", "Zambia", "Zimbabwe"};
|
||||
String[] codes = new String[]{"AFG", "ALB", "DZA", "ASM", "AND", "AGO", "AIA", "ATG", "ARG", "ARM", "ABW", "AUS", "AUT", "AZE", "BHM", "BHR", "BGD", "BRB", "BLR", "BEL", "BLZ", "BEN", "BMU", "BTN", "BOL", "BIH", "BWA", "BRA", "VGB", "BRN", "BGR", "BFA", "MMR", "BDI", "CPV", "KHM", "CMR", "CAN", "CYM", "CAF", "TCD", "CHL", "CHN", "COL", "COM", "COD", "COG", "COK", "CRI", "CIV", "HRV", "CUB", "CUW", "CYP", "CZE", "DNK", "DJI", "DMA", "DOM", "ECU", "EGY", "SLV", "GNQ", "ERI", "EST", "ETH", "FLK", "FRO", "FJI", "FIN", "FRA", "PYF", "GAB", "GMB", "GEO", "DEU", "GHA", "GIB", "GRC", "GRL", "GRD", "GUM", "GTM", "GGY", "GNB", "GIN", "GUY", "HTI", "HND", "HKG", "HUN", "ISL", "IND", "IDN", "IRN", "IRQ", "IRL", "IMN", "ISR", "ITA", "JAM", "JPN", "JEY", "JOR", "KAZ", "KEN", "KIR", "KOR", "PRK", "KSV", "KWT", "KGZ", "LAO", "LVA", "LBN", "LSO", "LBR", "LBY", "LIE", "LTU", "LUX", "MAC", "MKD", "MDG", "MWI", "MYS", "MDV", "MLI", "MLT", "MHL", "MRT", "MUS", "MEX", "FSM", "MDA", "MCO", "MNG", "MNE", "MAR", "MOZ", "NAM", "NPL", "NLD", "NCL", "NZL", "NIC", "NGA", "NER", "NIU", "MNP", "NOR", "OMN", "PAK", "PLW", "PAN", "PNG", "PRY", "PER", "PHL", "POL", "PRT", "PRI", "QAT", "ROU", "RUS", "RWA", "KNA", "LCA", "MAF", "SPM", "VCT", "WSM", "SMR", "STP", "SAU", "SEN", "SRB", "SYC", "SLE", "SGP", "SXM", "SVK", "SVN", "SLB", "SOM", "ZAF", "SSD", "ESP", "LKA", "SDN", "SUR", "SWZ", "SWE", "CHE", "SYR", "TWN", "TJK", "TZA", "THA", "TLS", "TGO", "TON", "TTO", "TUN", "TUR", "TKM", "TUV", "UGA", "UKR", "ARE", "GBR", "USA", "URY", "UZB", "VUT", "VEN", "VNM", "VGB", "WBG", "YEM", "ZMB", "ZWE"};
|
||||
for (int i = 0; i < countries.length; i++) {
|
||||
@ -66,4 +33,38 @@ public class WorldMap {
|
||||
}
|
||||
return geoCodes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toHighChartsSeries() {
|
||||
Map<String, Integer> geoCodeCounts = new HashMap<>();
|
||||
Map<String, String> geoCodes = getGeoCodes(geoCodeCounts);
|
||||
|
||||
for (String geoLocation : geoLocations) {
|
||||
String countryCode = geoCodes.get(geoLocation);
|
||||
if (countryCode != null) {
|
||||
geoCodeCounts.computeIfPresent(countryCode, (computedCountry, amount) -> amount + 1);
|
||||
}
|
||||
}
|
||||
|
||||
StringBuilder dataBuilder = new StringBuilder("[");
|
||||
|
||||
int i = 0;
|
||||
int size = geoCodeCounts.size();
|
||||
for (Map.Entry<String, Integer> entry : geoCodeCounts.entrySet()) {
|
||||
String geoCode = entry.getKey();
|
||||
Integer players = entry.getValue();
|
||||
|
||||
if (players != 0) {
|
||||
dataBuilder.append("{'code':'").append(geoCode).append("','value':").append(players).append("}");
|
||||
if (i < size - 1) {
|
||||
dataBuilder.append(",");
|
||||
}
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
|
||||
dataBuilder.append("]");
|
||||
return dataBuilder.toString();
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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 com.djrapitops.plan.utilities.html.graphs.line;
|
||||
|
||||
import com.djrapitops.plan.utilities.analysis.DouglasPeuckerAlgorithm;
|
||||
import com.djrapitops.plan.utilities.analysis.Point;
|
||||
import com.djrapitops.plan.utilities.analysis.ReduceGapTriangles;
|
||||
import com.djrapitops.plan.utilities.html.graphs.HighChart;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This is a LineGraph for any set of Points, thus it is Abstract.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class AbstractLineGraph implements HighChart {
|
||||
|
||||
protected List<Point> points;
|
||||
protected boolean reduceGapTriangles = false;
|
||||
protected boolean reducePoints = false;
|
||||
|
||||
public AbstractLineGraph() {
|
||||
points = new ArrayList<>();
|
||||
}
|
||||
|
||||
public AbstractLineGraph(List<Point> points) {
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toHighChartsSeries() {
|
||||
StringBuilder arrayBuilder = new StringBuilder("[");
|
||||
|
||||
if (reducePoints) {
|
||||
points = DouglasPeuckerAlgorithm.reducePoints(points, 0);
|
||||
}
|
||||
if (reduceGapTriangles) {
|
||||
points = ReduceGapTriangles.reduce(points);
|
||||
}
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
public void reduceGapTriangles() {
|
||||
this.reduceGapTriangles = true;
|
||||
}
|
||||
|
||||
public void reducePoints() {
|
||||
this.reducePoints = true;
|
||||
}
|
||||
|
||||
public void setPoints(List<Point> points) {
|
||||
this.points = points;
|
||||
}
|
||||
|
||||
public void addPoints(Collection<Point> points) {
|
||||
this.points.addAll(points);
|
||||
}
|
||||
}
|
@ -6,19 +6,22 @@ import com.djrapitops.plan.utilities.analysis.Point;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class CPUGraph {
|
||||
/**
|
||||
* Graph about CPU Usage gathered by TPSCountTimer.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class CPUGraph extends AbstractLineGraph {
|
||||
|
||||
/**
|
||||
* Constructor used to hide the public constructor
|
||||
*/
|
||||
private CPUGraph() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
public CPUGraph(List<TPS> tpsData) {
|
||||
super(transformToPoints(tpsData));
|
||||
}
|
||||
|
||||
public static String createSeries(List<TPS> tpsData) {
|
||||
List<Point> points = tpsData.stream()
|
||||
private static List<Point> transformToPoints(List<TPS> tpsData) {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getCPUUsage()))
|
||||
.collect(Collectors.toList());
|
||||
return LineSeries.createSeries(points, true);
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,27 @@
|
||||
package com.djrapitops.plan.utilities.html.graphs.line;
|
||||
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.utilities.analysis.Point;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Graph about Chunk Counts gathered by TPSCountTimer.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class ChunkGraph extends AbstractLineGraph {
|
||||
|
||||
public ChunkGraph(List<TPS> tpsData) {
|
||||
super(turnToPoints(tpsData));
|
||||
}
|
||||
|
||||
private static List<Point> turnToPoints(List<TPS> tpsData) {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getChunksLoaded()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package com.djrapitops.plan.utilities.html.graphs.line;
|
||||
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.utilities.analysis.Point;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Graph about Entity Counts gathered by TPSCountTimer.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class EntityGraph extends AbstractLineGraph {
|
||||
|
||||
public EntityGraph(List<TPS> tpsData) {
|
||||
super(turnToPoints(tpsData));
|
||||
}
|
||||
|
||||
private static List<Point> turnToPoints(List<TPS> tpsData) {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getEntityCount()))
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
}
|
@ -1,56 +0,0 @@
|
||||
/*
|
||||
* 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 com.djrapitops.plan.utilities.html.graphs.line;
|
||||
|
||||
import com.djrapitops.plan.utilities.analysis.Point;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Abstract scatter graph creator used by other graph creators.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 3.5.2
|
||||
*/
|
||||
public class LineSeries {
|
||||
|
||||
/**
|
||||
* Constructor used to hide the public constructor
|
||||
*/
|
||||
private LineSeries() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
public static String createSeries(List<Point> points, boolean reduceGapTriangles) {
|
||||
return createSeries(points, reduceGapTriangles, true);
|
||||
}
|
||||
|
||||
public static String createSeries(List<Point> points, boolean reduceGapTriangles, boolean reducePoints) {
|
||||
StringBuilder arrayBuilder = new StringBuilder("[");
|
||||
|
||||
// if (reducePoints) {
|
||||
// points = DouglasPeuckerAlgorithm.reducePoints(points, 0);
|
||||
// }
|
||||
//
|
||||
// if (reduceGapTriangles) {
|
||||
// points = ReduceGapTriangles.reduce(points);
|
||||
// }
|
||||
|
||||
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();
|
||||
}
|
||||
}
|
@ -7,21 +7,21 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Graph about Player Counts gathered by TPSCountTimer.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class PlayerActivityGraph {
|
||||
public class OnlineActivityGraph extends AbstractLineGraph {
|
||||
|
||||
/**
|
||||
* Constructor used to hide the public constructor
|
||||
*/
|
||||
private PlayerActivityGraph() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
public OnlineActivityGraph(List<TPS> tpsData) {
|
||||
super(turnToPoints(tpsData));
|
||||
}
|
||||
|
||||
public static String createSeries(List<TPS> tpsData) {
|
||||
List<Point> points = tpsData.stream()
|
||||
private static List<Point> turnToPoints(List<TPS> tpsData) {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getPlayers()))
|
||||
.collect(Collectors.toList());
|
||||
return LineSeries.createSeries(points, true);
|
||||
}
|
||||
}
|
@ -1,38 +1,27 @@
|
||||
package com.djrapitops.plan.utilities.html.graphs.line;
|
||||
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.system.tasks.TPSCountTimer;
|
||||
import com.djrapitops.plan.utilities.analysis.Point;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Class for creating scatter graph data from RAM Usage snapshots with TPS task.
|
||||
* Graph about RAM Usage gathered by TPSCountTimer.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see TPSCountTimer
|
||||
* @since 3.6.0
|
||||
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class RamGraph {
|
||||
public class RamGraph extends AbstractLineGraph {
|
||||
|
||||
/**
|
||||
* Constructor used to hide the public constructor
|
||||
*/
|
||||
private RamGraph() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
public RamGraph(List<TPS> tpsData) {
|
||||
super(turnToPoints(tpsData));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a series data string from given data.
|
||||
*
|
||||
* @param tpsData TPS Data collected by TPSCountTimer, one data point for each minute.
|
||||
* @return Series data for HighCharts
|
||||
*/
|
||||
public static String createSeries(List<TPS> tpsData) {
|
||||
List<Point> points = tpsData.stream()
|
||||
private static List<Point> turnToPoints(List<TPS> tpsData) {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getUsedMemory()))
|
||||
.collect(Collectors.toList());
|
||||
return LineSeries.createSeries(points, true);
|
||||
}
|
||||
}
|
||||
|
@ -1,33 +0,0 @@
|
||||
package com.djrapitops.plan.utilities.html.graphs.line;
|
||||
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ServerPreferencePie {
|
||||
|
||||
private ServerPreferencePie() {
|
||||
throw new IllegalStateException("Utility Class");
|
||||
}
|
||||
|
||||
public static String createSeries(Map<UUID, String> serverNames, Map<UUID, WorldTimes> serverWorldTimes) {
|
||||
StringBuilder seriesBuilder = new StringBuilder("[");
|
||||
int i = 0;
|
||||
int size = serverWorldTimes.size();
|
||||
for (Map.Entry<UUID, WorldTimes> server : serverWorldTimes.entrySet()) {
|
||||
String serverName = serverNames.getOrDefault(server.getKey(), "Unknown");
|
||||
seriesBuilder.append("{name:'").append(serverName)
|
||||
.append("',y:").append(server.getValue().getTotal());
|
||||
|
||||
seriesBuilder.append("}");
|
||||
if (i < size - 1) {
|
||||
seriesBuilder.append(",");
|
||||
}
|
||||
i++;
|
||||
}
|
||||
seriesBuilder.append("]");
|
||||
|
||||
return seriesBuilder.toString();
|
||||
}
|
||||
}
|
@ -7,23 +7,21 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Graph about TPS gathered by TPSCountTimer.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 3.5.0
|
||||
* @see com.djrapitops.plan.system.tasks.TPSCountTimer
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class TPSGraph {
|
||||
public class TPSGraph extends AbstractLineGraph {
|
||||
|
||||
/**
|
||||
* Constructor used to hide the public constructor
|
||||
*/
|
||||
private TPSGraph() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
public TPSGraph(List<TPS> tpsData) {
|
||||
super(turnToPoints(tpsData));
|
||||
}
|
||||
|
||||
public static String createSeries(List<TPS> tpsData) {
|
||||
List<Point> points = tpsData.stream()
|
||||
private static List<Point> turnToPoints(List<TPS> tpsData) {
|
||||
return tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getTicksPerSecond()))
|
||||
.collect(Collectors.toList());
|
||||
return LineSeries.createSeries(points, true);
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
package com.djrapitops.plan.utilities.html.graphs.line;
|
||||
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.system.tasks.TPSCountTimer;
|
||||
import com.djrapitops.plan.utilities.analysis.Point;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* Class for creating scatter graph data from Chunk and Entity load snapshots with TPS task.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see TPSCountTimer
|
||||
* @since 3.6.0
|
||||
*/
|
||||
public class WorldLoadGraph {
|
||||
|
||||
/**
|
||||
* Constructor used to hide the public constructor
|
||||
*/
|
||||
private WorldLoadGraph() {
|
||||
throw new IllegalStateException("Utility class");
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates series graph data of entity load.
|
||||
*
|
||||
* @param tpsData TPS Data collected by TPSCountTimer, one data point for each minute.
|
||||
* @return Series data for HighCharts
|
||||
*/
|
||||
public static String createSeriesEntities(List<TPS> tpsData) {
|
||||
List<Point> points = tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getEntityCount()))
|
||||
.collect(Collectors.toList());
|
||||
return LineSeries.createSeries(points, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates series data of chunk load.
|
||||
*
|
||||
* @param tpsData TPS Data collected by TPSCountTimer, one data point for each minute.
|
||||
* @return Series data for HighCharts
|
||||
*/
|
||||
public static String createSeriesChunks(List<TPS> tpsData) {
|
||||
List<Point> points = tpsData.stream()
|
||||
.map(tps -> new Point(tps.getDate(), tps.getChunksLoaded()))
|
||||
.collect(Collectors.toList());
|
||||
return LineSeries.createSeries(points, true);
|
||||
}
|
||||
}
|
@ -4,19 +4,36 @@
|
||||
*/
|
||||
package com.djrapitops.plan.utilities.html.graphs.pie;
|
||||
|
||||
import com.djrapitops.plan.utilities.html.graphs.HighChart;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PieSeries data creation utility class.
|
||||
* This is a PieChart for any set of PieSlices, thus it is Abstract.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class PieSeries {
|
||||
private PieSeries() {
|
||||
throw new IllegalStateException("Utility Class");
|
||||
public class AbstractPieChart implements HighChart {
|
||||
|
||||
protected List<PieSlice> slices;
|
||||
|
||||
public AbstractPieChart() {
|
||||
slices = new ArrayList<>();
|
||||
}
|
||||
|
||||
public AbstractPieChart(List<PieSlice> slices) {
|
||||
this.slices = slices;
|
||||
}
|
||||
|
||||
@Deprecated
|
||||
public static String createSeries(List<PieSlice> slices) {
|
||||
return new AbstractPieChart(slices).toHighChartsSeries();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toHighChartsSeries() {
|
||||
StringBuilder seriesBuilder = new StringBuilder("[");
|
||||
int i = 0;
|
||||
int size = slices.size();
|
||||
@ -31,4 +48,12 @@ public class PieSeries {
|
||||
|
||||
return seriesBuilder.toString();
|
||||
}
|
||||
|
||||
public void setSlices(List<PieSlice> slices) {
|
||||
this.slices = slices;
|
||||
}
|
||||
|
||||
public void addSlices(List<PieSlice> slices) {
|
||||
this.slices.addAll(slices);
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Licence is provided in the jar as license.yml also here:
|
||||
* https://github.com/Rsl1122/Plan-PlayerAnalytics/blob/master/Plan/src/main/resources/license.yml
|
||||
*/
|
||||
package com.djrapitops.plan.utilities.html.graphs.pie;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* PieChart with a Pie about each slice as well.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public abstract class AbstractPieChartWithDrilldown extends AbstractPieChart {
|
||||
|
||||
public AbstractPieChartWithDrilldown() {
|
||||
}
|
||||
|
||||
public AbstractPieChartWithDrilldown(List<PieSlice> slices) {
|
||||
super(slices);
|
||||
}
|
||||
|
||||
public abstract String toHighChartsDrilldown();
|
||||
|
||||
}
|
@ -4,40 +4,39 @@
|
||||
*/
|
||||
package com.djrapitops.plan.utilities.html.graphs.pie;
|
||||
|
||||
import com.djrapitops.plan.data.element.ActivityIndex;
|
||||
import com.djrapitops.plan.settings.theme.Theme;
|
||||
import com.djrapitops.plan.settings.theme.ThemeVal;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Utility class for creating Activity Pie data.
|
||||
* Pie about different Activity Groups defined by ActivityIndex.
|
||||
*
|
||||
* @author Rsl1122
|
||||
* @see ActivityIndex
|
||||
* @since 4.2.0
|
||||
*/
|
||||
public class ActivityPie {
|
||||
public class ActivityPie extends AbstractPieChart {
|
||||
|
||||
private ActivityPie() {
|
||||
throw new IllegalStateException("Utility Class");
|
||||
public ActivityPie(Map<String, Set<UUID>> activityData) {
|
||||
super(turnToSlices(activityData));
|
||||
}
|
||||
|
||||
public static String[] getSliceNames() {
|
||||
return new String[]{"Very Active", "Active", "Regular", "Irregular", "Inactive"};
|
||||
}
|
||||
|
||||
public static String createSeries(Map<String, Set<UUID>> activityData) {
|
||||
private static List<PieSlice> turnToSlices(Map<String, Set<UUID>> activityData) {
|
||||
String[] colors = Theme.getValue(ThemeVal.GRAPH_ACTIVITY_PIE).split(", ");
|
||||
int maxCol = colors.length;
|
||||
|
||||
List<PieSlice> slices = new ArrayList<>();
|
||||
int i = 0;
|
||||
for (String slice : getSliceNames()) {
|
||||
Set<UUID> players = activityData.getOrDefault(slice, new HashSet<>());
|
||||
for (String group : ActivityIndex.getGroups()) {
|
||||
Set<UUID> players = activityData.getOrDefault(group, new HashSet<>());
|
||||
int num = players.size();
|
||||
|
||||
slices.add(new PieSlice(slice, num, colors[i % maxCol], false));
|
||||
slices.add(new PieSlice(group, num, colors[i % maxCol], false));
|
||||
i++;
|
||||
}
|
||||
|
||||
return PieSeries.createSeries(slices);
|
||||
return slices;
|
||||
}
|
||||
}
|
@ -15,6 +15,18 @@ public class PieSlice {
|
||||
private final String color;
|
||||
private final boolean drilldown;
|
||||
|
||||
public PieSlice(String name, long y) {
|
||||
this(name, y, null, false);
|
||||
}
|
||||
|
||||
public PieSlice(String name, long y, String color) {
|
||||
this(name, y, color, false);
|
||||
}
|
||||
|
||||
public PieSlice(String name, long y, boolean drilldown) {
|
||||
this(name, y, null, drilldown);
|
||||
}
|
||||
|
||||
public PieSlice(String name, long y, String color, boolean drilldown) {
|
||||
this.name = name;
|
||||
this.y = y;
|
||||
@ -25,8 +37,8 @@ public class PieSlice {
|
||||
@Override
|
||||
public String toString() {
|
||||
return "{name:'" + name + "'," +
|
||||
"y:" + y + "," +
|
||||
"color:" + color
|
||||
"y:" + y
|
||||
+ (color != null ? "," + "color:" + color : "")
|
||||
+ (drilldown ? "," + "drilldown: '" + name + "'" : "")
|
||||
+ "}";
|
||||
}
|
||||
|
@ -0,0 +1,31 @@
|
||||
package com.djrapitops.plan.utilities.html.graphs.pie;
|
||||
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
public class ServerPreferencePie extends AbstractPieChart {
|
||||
|
||||
public ServerPreferencePie(Map<UUID, String> serverNames, Map<UUID, WorldTimes> serverWorldTimes) {
|
||||
super(turnToSlices(serverNames, serverWorldTimes));
|
||||
}
|
||||
|
||||
private static List<PieSlice> turnToSlices(Map<UUID, String> serverNames, Map<UUID, WorldTimes> serverWorldTimes) {
|
||||
List<PieSlice> slices = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<UUID, WorldTimes> server : serverWorldTimes.entrySet()) {
|
||||
UUID serverUUID = server.getKey();
|
||||
WorldTimes worldTimes = server.getValue();
|
||||
|
||||
String serverName = serverNames.getOrDefault(serverUUID, "Unknown");
|
||||
long num = worldTimes.getTotal();
|
||||
|
||||
slices.add(new PieSlice(serverName, num));
|
||||
}
|
||||
|
||||
return slices;
|
||||
}
|
||||
}
|
@ -11,30 +11,18 @@ import com.djrapitops.plan.utilities.comparators.PieSliceComparator;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class WorldPie {
|
||||
public class WorldPie extends AbstractPieChartWithDrilldown {
|
||||
|
||||
private WorldPie() {
|
||||
throw new IllegalStateException("Utility Class");
|
||||
}
|
||||
private WorldTimes worldTimes;
|
||||
|
||||
/**
|
||||
* Used to create HighCharts series string for series and drilldown.
|
||||
*
|
||||
* @param worldTimes WorldTimes object.
|
||||
* @return String array, index 0: Series data, 1: drilldown data
|
||||
*/
|
||||
public static String[] createSeries(WorldTimes worldTimes) {
|
||||
List<PieSlice> slices = turnIntoSlices(worldTimes);
|
||||
public WorldPie(WorldTimes worldTimes) {
|
||||
super(turnIntoSlices(worldTimes));
|
||||
|
||||
this.worldTimes = worldTimes;
|
||||
|
||||
if (Settings.ORDER_WORLD_PIE_BY_PERC.isTrue()) {
|
||||
slices.sort(new PieSliceComparator());
|
||||
}
|
||||
|
||||
String seriesData = PieSeries.createSeries(slices);
|
||||
|
||||
String drilldownData = createDrilldown(worldTimes);
|
||||
|
||||
return new String[]{seriesData, drilldownData};
|
||||
}
|
||||
|
||||
private static List<PieSlice> turnIntoSlices(WorldTimes worldTimes) {
|
||||
@ -59,6 +47,7 @@ public class WorldPie {
|
||||
}
|
||||
i++;
|
||||
}
|
||||
|
||||
return slices;
|
||||
}
|
||||
|
||||
@ -68,8 +57,9 @@ public class WorldPie {
|
||||
return transformToAliases(playtimePerWorld, aliases);
|
||||
}
|
||||
|
||||
// TODO Move to another class
|
||||
public static Map<String, Long> transformToAliases(Map<String, Long> playtimePerWorld, Map<String, String> aliases) {
|
||||
// TODO Optimization is possible
|
||||
// TODO Optimization is possible (WorldAliasSettings)
|
||||
WorldAliasSettings aliasSettings = new WorldAliasSettings();
|
||||
|
||||
Map<String, Long> playtimePerAlias = new HashMap<>();
|
||||
@ -89,7 +79,8 @@ public class WorldPie {
|
||||
return playtimePerAlias;
|
||||
}
|
||||
|
||||
private static String createDrilldown(WorldTimes worldTimes) {
|
||||
@Override
|
||||
public String toHighChartsDrilldown() {
|
||||
StringBuilder drilldownBuilder = new StringBuilder();
|
||||
int i = 0;
|
||||
|
||||
@ -118,8 +109,8 @@ public class WorldPie {
|
||||
return drilldownBuilder.toString();
|
||||
}
|
||||
|
||||
private static Map<String, GMTimes> transformToGMAliases(Map<String, GMTimes> gmTimesMap) {
|
||||
// TODO Optimization is possible
|
||||
private Map<String, GMTimes> transformToGMAliases(Map<String, GMTimes> gmTimesMap) {
|
||||
// TODO Optimization is possible (WorldAliasSettings)
|
||||
WorldAliasSettings aliasSettings = new WorldAliasSettings();
|
||||
Map<String, String> aliases = aliasSettings.getAliases();
|
||||
|
||||
@ -138,16 +129,16 @@ public class WorldPie {
|
||||
|
||||
String alias = aliases.get(worldName);
|
||||
|
||||
GMTimes aliasGMtimes = gmTimesPerAlias.getOrDefault(alias, new GMTimes());
|
||||
GMTimes aliasGMTimes = gmTimesPerAlias.getOrDefault(alias, new GMTimes());
|
||||
for (String gm : gms) {
|
||||
aliasGMtimes.addTime(gm, gmTimes.getTime(gm));
|
||||
aliasGMTimes.addTime(gm, gmTimes.getTime(gm));
|
||||
}
|
||||
gmTimesPerAlias.put(alias, aliasGMtimes);
|
||||
gmTimesPerAlias.put(alias, aliasGMTimes);
|
||||
}
|
||||
return gmTimesPerAlias;
|
||||
}
|
||||
|
||||
private static void appendGMTimesForWorld(StringBuilder drilldownBuilder, Map.Entry<String, GMTimes> world) {
|
||||
private void appendGMTimesForWorld(StringBuilder drilldownBuilder, Map.Entry<String, GMTimes> world) {
|
||||
Map<String, Long> gmTimes = world.getValue().getTimes();
|
||||
int smallSize = gmTimes.size();
|
||||
int j = 0;
|
||||
|
@ -68,7 +68,7 @@ public class ServerAccordionCreator {
|
||||
String worldId = "worldPieServer" + sanitizedServerName;
|
||||
AnalysisUtils.addMissingWorlds(worldTimes);
|
||||
|
||||
String[] worldData = WorldPie.createSeries(worldTimes);
|
||||
WorldPie worldPie = new WorldPie(worldTimes);
|
||||
|
||||
// Accordion panel header
|
||||
html.append("<div class=\"panel panel-col-").append(Theme.getValue(ThemeVal.PARSED_SERVER_ACCORDION)).append("\">")
|
||||
@ -104,8 +104,8 @@ public class ServerAccordionCreator {
|
||||
.append("<div id=\"").append(worldId).append("\" class=\"dashboard-donut-chart\"></div>")
|
||||
// World Pie data script
|
||||
.append("<script>")
|
||||
.append("var ").append(worldId).append("series = {name:'World Playtime'," +/*colors: worldPieColors,*/"colorByPoint:true,data:").append(worldData[0]).append("};")
|
||||
.append("var ").append(worldId).append("gmseries = ").append(worldData[1]).append(";")
|
||||
.append("var ").append(worldId).append("series = {name:'World Playtime',colorByPoint:true,data:").append(worldPie.toHighChartsSeries()).append("};")
|
||||
.append("var ").append(worldId).append("gmseries = ").append(worldPie.toHighChartsDrilldown()).append(";")
|
||||
.append("</script>")
|
||||
.append("</div>") // Right col-6
|
||||
.append("</div>") // Closes row clearfix
|
||||
|
@ -87,7 +87,7 @@ public class SessionTabStructureCreator {
|
||||
WorldTimes worldTimes = session.getWorldTimes();
|
||||
AnalysisUtils.addMissingWorlds(worldTimes);
|
||||
|
||||
String[] worldData = WorldPie.createSeries(worldTimes);
|
||||
WorldPie worldPie = new WorldPie(worldTimes);
|
||||
|
||||
String killTable = KillsTableCreator.createTable(session.getPlayerKills());
|
||||
|
||||
@ -131,8 +131,8 @@ public class SessionTabStructureCreator {
|
||||
.append("<div id=\"").append(worldId).append("\" class=\"dashboard-donut-chart\"></div>")
|
||||
// World Pie data script
|
||||
.append("<script>")
|
||||
.append("var ").append(worldId).append("series = {name:'World Playtime'," +/*colors: worldPieColors,*/"colorByPoint:true,data:").append(worldData[0]).append("};")
|
||||
.append("var ").append(worldId).append("gmseries = ").append(worldData[1]).append(";")
|
||||
.append("var ").append(worldId).append("series = {name:'World Playtime',colorByPoint:true,data:").append(worldPie.toHighChartsSeries()).append("};")
|
||||
.append("var ").append(worldId).append("gmseries = ").append(worldPie.toHighChartsDrilldown()).append(";")
|
||||
.append("</script>")
|
||||
.append("</div>") // Right col-6
|
||||
.append("</div>") // Closes row clearfix
|
||||
|
@ -8,12 +8,10 @@ import com.djrapitops.plan.data.container.Session;
|
||||
import com.djrapitops.plan.data.container.TPS;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.utilities.analysis.Point;
|
||||
import com.djrapitops.plan.utilities.html.graphs.PunchCardGraph;
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.*;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.bukkit.plugin.java.JavaPlugin;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.powermock.core.classloader.annotations.PrepareForTest;
|
||||
@ -21,9 +19,10 @@ import org.powermock.modules.junit4.PowerMockRunner;
|
||||
import test.utilities.RandomData;
|
||||
import test.utilities.TestInit;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static junit.framework.TestCase.assertEquals;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* @author Fuzzlemann
|
||||
@ -52,69 +51,20 @@ public class GraphTest {
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGraphCreators() {
|
||||
String expected = "[[0,0.0],[1,1.0],[2,2.0],[3,3.0],[4,4.0],[5,5.0],[6,6.0],[7,7.0],[8,8.0],[9,9.0]]";
|
||||
assertEquals(expected, CPUGraph.createSeries(tpsList));
|
||||
assertEquals(expected, PlayerActivityGraph.createSeries(tpsList));
|
||||
// TODO Fix TimeZone Dependency of this test
|
||||
// assertEquals("[{x:3600000, y:3, z:14, marker: { radius:14}},]", PunchCardGraph.createSeries(sessionList));
|
||||
|
||||
assertEquals(expected, RamGraph.createSeries(tpsList));
|
||||
assertEquals(expected, TPSGraph.createSeries(tpsList));
|
||||
assertEquals(expected, WorldLoadGraph.createSeriesChunks(tpsList));
|
||||
assertEquals(expected, WorldLoadGraph.createSeriesEntities(tpsList));
|
||||
// assertEquals("[{'code':'1','value':1},{'code':'2','value':2},{'code':'3','value':3},{'code':'4','value':4},{'code':'5','value':5},{'code':'6','value':6},{'code':'7','value':7},{'code':'8','value':8},{'code':'9','value':9}]", WorldMap.createSeries(geoList));
|
||||
// TODO fix config mock dependency
|
||||
// assertEquals("[[{name:'WORLD',y:0,drilldown: 'WORLD'}], [{name:'WORLD', id:'WORLD',colors: gmPieColors,data: [['SURVIVAL',0],['SPECTATOR',0],['CREATIVE',0],['ADVENTURE',0]]}]]",
|
||||
// Arrays.toString(WorldPie.createSeries(worldTimes)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGraphCreatorsForBracketMistakes() {
|
||||
String[] series = new String[]{
|
||||
CPUGraph.createSeries(tpsList),
|
||||
PlayerActivityGraph.createSeries(tpsList),
|
||||
PunchCardGraph.createSeries(sessionList),
|
||||
RamGraph.createSeries(tpsList),
|
||||
TPSGraph.createSeries(tpsList),
|
||||
WorldLoadGraph.createSeriesChunks(tpsList),
|
||||
WorldLoadGraph.createSeriesEntities(tpsList),
|
||||
// WorldMap.createSeries(geoList),
|
||||
// TODO fix config mock dependency
|
||||
// Arrays.toString(WorldPie.createSeries(worldTimes))
|
||||
@Ignore("Test should use Stack instead")
|
||||
public void testLineGraphsForBracketErrors() {
|
||||
AbstractLineGraph[] graphs = new AbstractLineGraph[]{
|
||||
new CPUGraph(tpsList),
|
||||
new OnlineActivityGraph(tpsList),
|
||||
new RamGraph(tpsList),
|
||||
new TPSGraph(tpsList),
|
||||
new EntityGraph(tpsList),
|
||||
new ChunkGraph(tpsList)
|
||||
};
|
||||
for (String test : series) {
|
||||
int opened = StringUtils.countMatches(test, "{");
|
||||
int closed = StringUtils.countMatches(test, "}");
|
||||
Assert.assertEquals(opened, closed);
|
||||
opened = StringUtils.countMatches(test, "[");
|
||||
closed = StringUtils.countMatches(test, "]");
|
||||
Assert.assertEquals(opened, closed);
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testSeriesCreator() {
|
||||
String result = StringUtils.removeAll(LineSeries.createSeries(points, false, false), "[\\[\\]]");
|
||||
String[] splittedResult = result.split(",");
|
||||
|
||||
Map<String, String> expected = new LinkedHashMap<>();
|
||||
|
||||
for (int i = 0; i < splittedResult.length; i++) {
|
||||
expected.put(splittedResult[i++], splittedResult[i]);
|
||||
}
|
||||
|
||||
int i2 = 0;
|
||||
for (Map.Entry<String, String> entry : expected.entrySet()) {
|
||||
String expectedX = entry.getKey();
|
||||
String expectedY = entry.getValue();
|
||||
|
||||
Point point = points.get(i2);
|
||||
|
||||
assertEquals("Given X does not match expected X", expectedX, String.valueOf((long) point.getX()));
|
||||
assertEquals("Given Y does not match expected Y", expectedY, String.valueOf(point.getY()));
|
||||
|
||||
i2++;
|
||||
for (AbstractLineGraph graph : graphs) {
|
||||
String series = graph.toHighChartsSeries();
|
||||
// TODO Use Stack instead.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user