mirror of
https://github.com/plan-player-analytics/Plan.git
synced 2024-10-06 10:27:42 +02:00
Server ExtensionData visualization
This commit is contained in:
parent
09f7801934
commit
2ad5f979f6
@ -37,6 +37,7 @@ import com.djrapitops.plan.utilities.html.graphs.bar.BarGraph;
|
||||
import com.djrapitops.plan.utilities.html.graphs.line.PingGraph;
|
||||
import com.djrapitops.plan.utilities.html.graphs.pie.WorldPie;
|
||||
import com.djrapitops.plan.utilities.html.graphs.stack.StackGraph;
|
||||
import com.djrapitops.plan.utilities.html.pages.AnalysisPluginTabs;
|
||||
import com.djrapitops.plan.utilities.html.structure.Accordions;
|
||||
import com.djrapitops.plan.utilities.html.structure.AnalysisPluginsTabContentCreator;
|
||||
import com.djrapitops.plan.utilities.html.structure.RecentLoginList;
|
||||
@ -488,13 +489,14 @@ public class AnalysisContainer extends DynamicDataContainer {
|
||||
|
||||
private void addPluginSuppliers() {
|
||||
// TODO Refactor into a system that supports running the analysis on Bungee
|
||||
Key<String[]> navAndTabs = new Key<>(new Type<String[]>() {
|
||||
}, "NAV_AND_TABS");
|
||||
Key<String[]> navAndTabs = new Key<>(new Type<String[]>() {}, "NAV_AND_TABS");
|
||||
Key<AnalysisPluginTabs> pluginTabs = new Key<>(AnalysisPluginTabs.class, "PLUGIN_TABS");
|
||||
putCachingSupplier(navAndTabs, () -> pluginsTabContentCreator.createContent(
|
||||
this, getValue(AnalysisKeys.PLAYERS_MUTATOR).orElse(new PlayersMutator(new ArrayList<>()))
|
||||
));
|
||||
putSupplier(AnalysisKeys.PLUGINS_TAB_NAV, () -> getUnsafe(navAndTabs)[0]);
|
||||
putSupplier(AnalysisKeys.PLUGINS_TAB, () -> getUnsafe(navAndTabs)[1]);
|
||||
putCachingSupplier(pluginTabs, () -> new AnalysisPluginTabs(serverContainer.getValue(ServerKeys.EXTENSION_DATA).orElse(new ArrayList<>()), formatters));
|
||||
putSupplier(AnalysisKeys.PLUGINS_TAB_NAV, () -> getUnsafe(pluginTabs).getNav() + getUnsafe(navAndTabs)[0]);
|
||||
putSupplier(AnalysisKeys.PLUGINS_TAB, () -> getUnsafe(pluginTabs).getTabs() + getUnsafe(navAndTabs)[1]);
|
||||
}
|
||||
|
||||
@Singleton
|
||||
|
@ -25,6 +25,7 @@ import com.djrapitops.plan.data.store.Type;
|
||||
import com.djrapitops.plan.data.store.containers.PlayerContainer;
|
||||
import com.djrapitops.plan.data.store.objects.DateObj;
|
||||
import com.djrapitops.plan.data.time.WorldTimes;
|
||||
import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -63,4 +64,5 @@ public class ServerKeys {
|
||||
public static final Key<DateObj<Integer>> ALL_TIME_PEAK_PLAYERS = new Key<>(new Type<DateObj<Integer>>() {}, "all_time_peak_players");
|
||||
public static final Key<DateObj<Integer>> RECENT_PEAK_PLAYERS = new Key<>(new Type<DateObj<Integer>>() {}, "recent_peak_players");
|
||||
public static final Key<Map<String, Integer>> COMMAND_USAGE = new Key<>(new Type<Map<String, Integer>>() {}, "command_usage");
|
||||
public static final Key<List<ExtensionServerData>> EXTENSION_DATA = new Key<>(new Type<List<ExtensionServerData>>() {}, "extension_data");
|
||||
}
|
@ -27,6 +27,7 @@ import com.djrapitops.plan.db.access.queries.ServerAggregateQueries;
|
||||
import com.djrapitops.plan.db.access.queries.objects.ServerQueries;
|
||||
import com.djrapitops.plan.db.access.queries.objects.TPSQueries;
|
||||
import com.djrapitops.plan.db.access.queries.objects.WorldTimesQueries;
|
||||
import com.djrapitops.plan.extension.implementation.storage.queries.ExtensionServerDataQuery;
|
||||
import com.djrapitops.plan.system.cache.SessionCache;
|
||||
import com.djrapitops.plan.system.info.server.Server;
|
||||
|
||||
@ -94,6 +95,8 @@ public class ServerContainerQuery implements Query<ServerContainer> {
|
||||
container.putCachingSupplier(ServerKeys.MOB_KILL_COUNT, () -> SessionsMutator.forContainer(container).toMobKillCount());
|
||||
container.putCachingSupplier(ServerKeys.DEATH_COUNT, () -> SessionsMutator.forContainer(container).toDeathCount());
|
||||
|
||||
container.putCachingSupplier(ServerKeys.EXTENSION_DATA, () -> db.query(new ExtensionServerDataQuery(serverUUID)));
|
||||
|
||||
return container;
|
||||
}
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
/*
|
||||
* 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.utilities.html.pages;
|
||||
|
||||
import com.djrapitops.plan.extension.FormatType;
|
||||
import com.djrapitops.plan.extension.implementation.TabInformation;
|
||||
import com.djrapitops.plan.extension.implementation.results.ExtensionDescriptive;
|
||||
import com.djrapitops.plan.extension.implementation.results.ExtensionInformation;
|
||||
import com.djrapitops.plan.extension.implementation.results.ExtensionTabData;
|
||||
import com.djrapitops.plan.extension.implementation.results.server.ExtensionServerData;
|
||||
import com.djrapitops.plan.utilities.formatting.Formatter;
|
||||
import com.djrapitops.plan.utilities.formatting.Formatters;
|
||||
import com.djrapitops.plan.utilities.html.Html;
|
||||
import com.djrapitops.plan.utilities.html.icon.Icon;
|
||||
import com.djrapitops.plan.utilities.html.structure.TabsElement;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Responsible for generating /server page plugin tabs based on DataExtension API data.
|
||||
* <p>
|
||||
* Currently very similar to {@link InspectPluginTab}.
|
||||
* This will become more complex once tables are added, since some big tables will be moved to their own tabs.
|
||||
*
|
||||
* @author Rsl1122
|
||||
*/
|
||||
public class AnalysisPluginTabs {
|
||||
|
||||
private List<ExtensionServerData> serverData;
|
||||
|
||||
private Map<FormatType, Formatter<Long>> numberFormatters;
|
||||
|
||||
private Formatter<Double> decimalFormatter;
|
||||
private Formatter<Double> percentageFormatter;
|
||||
|
||||
private String nav;
|
||||
private String tab;
|
||||
|
||||
public AnalysisPluginTabs(String nav, String tab) {
|
||||
this.nav = nav;
|
||||
this.tab = tab;
|
||||
}
|
||||
|
||||
public AnalysisPluginTabs(
|
||||
List<ExtensionServerData> serverData,
|
||||
Formatters formatters
|
||||
) {
|
||||
this.serverData = serverData;
|
||||
|
||||
numberFormatters = new EnumMap<>(FormatType.class);
|
||||
numberFormatters.put(FormatType.DATE_SECOND, formatters.secondLong());
|
||||
numberFormatters.put(FormatType.DATE_YEAR, formatters.yearLong());
|
||||
numberFormatters.put(FormatType.TIME_MILLISECONDS, formatters.timeAmount());
|
||||
numberFormatters.put(FormatType.NONE, Object::toString);
|
||||
|
||||
this.decimalFormatter = formatters.decimals();
|
||||
this.percentageFormatter = formatters.percentage();
|
||||
|
||||
generate();
|
||||
}
|
||||
|
||||
public String getNav() {
|
||||
return nav;
|
||||
}
|
||||
|
||||
public String getTabs() {
|
||||
return tab;
|
||||
}
|
||||
|
||||
private void generate() {
|
||||
if (serverData.isEmpty()) {
|
||||
nav = "<li><a class=\"nav-button\" href=\"javascript:void(0)\">Extensions (No Data)</a></li>";
|
||||
tab = "<div class=\"tab\"><div class=\"row clearfix\">" +
|
||||
"<div class=\"col-md-12\">" + Html.CARD.parse("<p>No Extension Data</p>") +
|
||||
"</div></div></div>";
|
||||
} else {
|
||||
nav = "<li><a class=\"nav-button\" href=\"javascript:void(0)\">General</a></li>";
|
||||
tab = generatePageTab();
|
||||
}
|
||||
}
|
||||
|
||||
private String generatePageTab() {
|
||||
Collections.sort(serverData);
|
||||
|
||||
StringBuilder tabBuilder = new StringBuilder();
|
||||
|
||||
for (ExtensionServerData datum : serverData) {
|
||||
ExtensionInformation extensionInformation = datum.getExtensionInformation();
|
||||
|
||||
boolean onlyGeneric = datum.hasOnlyGenericTab();
|
||||
|
||||
String tabsElement;
|
||||
if (onlyGeneric) {
|
||||
ExtensionTabData genericTabData = datum.getTabs().get(0);
|
||||
tabsElement = Html.BODY.parse(parseDataHtml(genericTabData));
|
||||
} else {
|
||||
tabsElement = new TabsElement(
|
||||
datum.getTabs().stream().map(this::wrapToTabElementTab).toArray(TabsElement.Tab[]::new)
|
||||
).toHtmlFull();
|
||||
}
|
||||
|
||||
tabBuilder.append(wrapInContainer(extensionInformation, tabsElement));
|
||||
}
|
||||
|
||||
return wrapInTab(tabBuilder.toString());
|
||||
}
|
||||
|
||||
private String wrapInTab(String content) {
|
||||
return "<div class=\"tab\"><div class=\"row clearfix\">" + content + "</div></div>";
|
||||
}
|
||||
|
||||
private TabsElement.Tab wrapToTabElementTab(ExtensionTabData tabData) {
|
||||
TabInformation tabInformation = tabData.getTabInformation();
|
||||
|
||||
return new TabsElement.Tab(tabInformation.getTabName(), parseDataHtml(tabData));
|
||||
}
|
||||
|
||||
private String parseDataHtml(ExtensionTabData tabData) {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (String key : tabData.getValueOrder()) {
|
||||
tabData.getBoolean(key).ifPresent(data -> append(builder, data.getDescriptive(), data.getFormattedValue()));
|
||||
tabData.getDouble(key).ifPresent(data -> append(builder, data.getDescriptive(), data.getFormattedValue(decimalFormatter)));
|
||||
tabData.getPercentage(key).ifPresent(data -> append(builder, data.getDescriptive(), data.getFormattedValue(percentageFormatter)));
|
||||
tabData.getNumber(key).ifPresent(data -> append(builder, data.getDescriptive(), data.getFormattedValue(numberFormatters.get(data.getFormatType()))));
|
||||
tabData.getString(key).ifPresent(data -> append(builder, data.getDescriptive(), data.getFormattedValue()));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
private void append(StringBuilder builder, ExtensionDescriptive descriptive, String formattedValue) {
|
||||
Optional<String> description = descriptive.getDescription();
|
||||
if (description.isPresent()) {
|
||||
builder.append("<p title=\"").append(description.get()).append("\">");
|
||||
} else {
|
||||
builder.append("<p>");
|
||||
}
|
||||
builder.append(Icon.fromExtensionIcon(descriptive.getIcon()))
|
||||
.append(' ').append(descriptive.getText()).append(": ").append(formattedValue).append("</p>");
|
||||
}
|
||||
|
||||
private String wrapInContainer(ExtensionInformation information, String tabsElement) {
|
||||
return "<div class=\"col-xs-12 col-sm-12 col-md-4 col-lg-4\"><div class=\"card\">" +
|
||||
"<div class=\"header\">" +
|
||||
"<h2>" + Icon.fromExtensionIcon(information.getIcon()) + ' ' + information.getPluginName() + "</h2>" +
|
||||
"</div>" +
|
||||
tabsElement +
|
||||
"</div></div>";
|
||||
}
|
||||
}
|
@ -68,7 +68,7 @@ public class AnalysisPluginsTabContentCreator {
|
||||
) {
|
||||
|
||||
if (mutator.all().isEmpty()) {
|
||||
return new String[]{"<li><a>No Data</a></li>", ""};
|
||||
return new String[]{"", ""};
|
||||
}
|
||||
|
||||
List<UUID> uuids = mutator.uuids();
|
||||
@ -125,7 +125,7 @@ public class AnalysisPluginsTabContentCreator {
|
||||
"</div></div>";
|
||||
|
||||
return new String[]{
|
||||
(displayGeneralTab ? "<li><a class=\"nav-button\" href=\"javascript:void(0)\">General</a></li>" : "")
|
||||
(displayGeneralTab ? "<li><a class=\"nav-button\" href=\"javascript:void(0)\">General (Legacy)</a></li>" : "")
|
||||
+ "<li><a class=\"nav-button\" href=\"javascript:void(0)\">Player Data</a></li>" + nav.toString(),
|
||||
(displayGeneralTab ? generalTab.toString() : "") + playerListTab + otherTabs.toString()
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user