Added a Stack graph for BuyCraft. (Each currency has own series)

This commit is contained in:
Rsl1122 2018-02-01 18:07:18 +02:00
parent ab58c06380
commit a6bd3eadcc
4 changed files with 145 additions and 4 deletions

View File

@ -31,6 +31,9 @@
<!-- AdminBSB Themes. You can choose a theme from css/themes instead of get all themes -->
<link href="css/themes/all-themes.css" rel="stylesheet"/>
<!-- Jquery Core Js -->
<script src="plugins/jquery/jquery.min.js"></script>
</head>
<body class="theme-red">
@ -907,9 +910,6 @@
</div>
</section>
<!-- Jquery Core Js -->
<script src="plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap Core Js -->
<script src="plugins/bootstrap/js/bootstrap.js"></script>

View File

@ -72,6 +72,15 @@ public class BuyCraftData extends PluginData {
);
}
analysisContainer.addTable("payTable", payTable);
MoneyStackGraph moneyStackGraph = MoneyStackGraph.create(payments);
String graphHtml = Html.PANEL_BODY.parse("<div id=\"buycraftChart\" class=\"dashboard-flot-chart\"></div>") +
"<script>$(function () {setTimeout(function() {" +
"stackChart('buycraftChart', "
+ moneyStackGraph.toHighChartsLabels() + ", "
+ moneyStackGraph.toHighChartsSeries() + ", '');}, 1000)});</script>";
analysisContainer.addHtml("moneygraph", graphHtml);
}
private void addPaymentTotals(AnalysisContainer analysisContainer, List<Payment> payments) {

View File

@ -0,0 +1,130 @@
/*
* 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.pluginbridge.plan.buycraft;
import com.djrapitops.plan.system.settings.Settings;
import com.djrapitops.plan.system.settings.theme.ThemeVal;
import com.djrapitops.plan.utilities.MiscUtils;
import com.djrapitops.plan.utilities.html.graphs.stack.AbstractStackGraph;
import com.djrapitops.plan.utilities.html.graphs.stack.StackDataSet;
import com.djrapitops.plugin.api.TimeAmount;
import java.time.Instant;
import java.time.LocalDate;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.time.format.TextStyle;
import java.util.*;
/**
* Utility for creating Money Stack Graph.
*
* @author Rsl1122
*/
public class MoneyStackGraph {
private final AbstractStackGraph stackGraph;
private MoneyStackGraph(AbstractStackGraph stackGraph) {
this.stackGraph = stackGraph;
}
public static MoneyStackGraph create(List<Payment> payments) {
long now = MiscUtils.getTime();
long oldestDate = payments.isEmpty() ? now : payments.get(payments.size() - 1).getDate();
String[] labels = getLabels(now, oldestDate);
Map<String, List<Payment>> stacks = getStacks(payments);
StackDataSet[] dataSets = getDataSets(labels, stacks);
return new MoneyStackGraph(new AbstractStackGraph(labels, dataSets));
}
private static StackDataSet[] getDataSets(String[] labels, Map<String, List<Payment>> stacks) {
String[] colors = ThemeVal.GRAPH_GM_PIE.getDefaultValue().split(", ");
int maxCol = colors.length;
List<StackDataSet> stackDataSets = new ArrayList<>();
int i = 0;
for (Map.Entry<String, List<Payment>> entry : stacks.entrySet()) {
String currency = entry.getKey();
List<Payment> payments = entry.getValue();
List<Double> values = sortValuesByLabels(labels, getValueMap(payments));
String color = colors[(i) % maxCol];
stackDataSets.add(new StackDataSet(values, currency, color));
i++;
}
return stackDataSets.toArray(new StackDataSet[stackDataSets.size()]);
}
private static List<Double> sortValuesByLabels(String[] labels, Map<String, Double> valueMap) {
List<Double> values = new ArrayList<>();
for (String label : labels) {
values.add(valueMap.getOrDefault(label, 0.0));
}
return values;
}
private static Map<String, Double> getValueMap(List<Payment> payments) {
Map<String, Double> valueMap = new HashMap<>();
for (Payment payment : payments) {
String label = getLabel(payment.getDate());
Double value = valueMap.getOrDefault(label, 0.0);
valueMap.put(label, value + payment.getAmount());
}
return valueMap;
}
private static Map<String, List<Payment>> getStacks(List<Payment> payments) {
Map<String, List<Payment>> stacks = new HashMap<>();
for (Payment payment : payments) {
String currency = payment.getCurrency();
List<Payment> dataSetPayments = stacks.getOrDefault(currency, new ArrayList<>());
dataSetPayments.add(payment);
stacks.put(currency, dataSetPayments);
}
return stacks;
}
private static String[] getLabels(long now, long oldestDate) {
long oneYearAgo = now - TimeAmount.YEAR.ms();
long leftLimit = Math.max(oldestDate, oneYearAgo);
List<String> labels = new ArrayList<>();
for (long time = leftLimit; time < now; time += TimeAmount.MONTH.ms()) {
labels.add(getLabel(time));
}
return labels.toArray(new String[labels.size()]);
}
private static String getLabel(long time) {
String locale = Settings.LOCALE.toString();
Locale usedLocale = locale.equalsIgnoreCase("default") ? Locale.ENGLISH : Locale.forLanguageTag(locale);
ZoneId usedTimeZone = Settings.USE_SERVER_TIME.isTrue() ? ZoneId.systemDefault() : ZoneOffset.UTC;
LocalDate date = Instant.ofEpochMilli(time).atZone(usedTimeZone).toLocalDate();
String month = date.getMonth().getDisplayName(TextStyle.FULL, usedLocale);
int year = date.getYear();
return month + " " + year;
}
public String toHighChartsLabels() {
return stackGraph.toHighChartsLabels();
}
public String toHighChartsSeries() {
return stackGraph.toHighChartsSeries();
}
}

View File

@ -9,6 +9,8 @@ import java.util.UUID;
/**
* Represents a BuyCraft payment.
*
* Payments are sorted most recent first by natural ordering.
*
* @author Rsl1122
*/
public class Payment implements Comparable<Payment> {
@ -55,6 +57,6 @@ public class Payment implements Comparable<Payment> {
@Override
public int compareTo(Payment o) {
return this.playerName.toLowerCase().compareTo(o.playerName.toLowerCase());
return -Long.compare(this.date, o.date);
}
}