Skip to content

Commit

Permalink
Ashwin/playtime charts 2 (#123)
Browse files Browse the repository at this point in the history
* wipfeat: jfreechart integration

* feat: working chart in stats command
  • Loading branch information
VanillaViking authored Sep 7, 2024
1 parent e7928e8 commit e129648
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 8 deletions.
8 changes: 7 additions & 1 deletion zyenyo-discord/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,13 @@
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.11.0</version>
</dependency>
</dependency>

<dependency>
<groupId>jfree</groupId>
<artifactId>jfreechart</artifactId>
<version>1.0.13</version>
</dependency>

</dependencies>

Expand Down
51 changes: 46 additions & 5 deletions zyenyo-discord/src/main/java/asynchronous/typing/Chart.java
Original file line number Diff line number Diff line change
@@ -1,11 +1,27 @@
package asynchronous.typing;

import java.io.IOException;
import java.io.File;

import org.json.simple.JSONObject;
import org.json.simple.JSONValue;

import java.util.LinkedHashMap;

import net.dv8tion.jda.api.events.message.MessageReceivedEvent;
import net.dv8tion.jda.api.EmbedBuilder;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.chart.axis.CategoryLabelPositions;

import java.awt.BasicStroke;

import zyenyo.Database;


public class Chart implements Runnable
Expand All @@ -18,12 +34,37 @@ public void run()
{
try
{
String jsonString = TypingApiHandler.requestData("chart/wpm/" + event.getAuthor().getId());
JSONObject json = (JSONObject) JSONValue.parse(jsonString);

event.getChannel().sendMessage(json.get("URL").toString())
.queue();
String id = event.getAuthor().getId();
LinkedHashMap<String, Integer> monthlyPlaycount = Database.playcount(id);

DefaultCategoryDataset lineChartDataset = new DefaultCategoryDataset();
monthlyPlaycount.forEach((monthStr, count) -> lineChartDataset.addValue(count, "playcount", monthStr));

JFreeChart lineChartObject = ChartFactory.createLineChart(
"Playcount","",
"",
lineChartDataset,PlotOrientation.VERTICAL,
true,true,false);
lineChartObject.removeLegend();

CategoryPlot plot = (CategoryPlot) lineChartObject.getPlot();

plot.getDomainAxis().setCategoryLabelPositions(
CategoryLabelPositions.UP_45);
plot.setDomainGridlinesVisible(true);
plot.setRangeGridlinesVisible(false);
plot.getRenderer().setSeriesStroke(0, new BasicStroke(2.0f));

int width = 640; /* Width of the image */
int height = 380; /* Height of the image */
File lineChart = new File( "LineChart.png" );
ChartUtilities.saveChartAsPNG(lineChart ,lineChartObject, width ,height);

EmbedBuilder embed = new EmbedBuilder().setTitle("Playcount").setImage("attachment://chart.png");
event.getChannel().sendMessageEmbeds( embed.build() ).addFile(lineChart, "chart.png").queue();

}
catch (IOException | InterruptedException e) {e.printStackTrace();}
catch (Exception e) {e.printStackTrace();}
}
}
54 changes: 53 additions & 1 deletion zyenyo-discord/src/main/java/asynchronous/typing/TypeStats.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,20 @@
package asynchronous.typing;

import java.io.File;

import java.awt.Color;
import java.awt.BasicStroke;

import java.util.concurrent.ExecutionException;
import java.util.LinkedHashMap;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.chart.axis.CategoryLabelPositions;

import org.json.JSONObject;

Expand Down Expand Up @@ -77,6 +90,8 @@ else if (args.length == 3 && args[2].equals("-g"))
double typingPoints = Double.parseDouble(json.get("weightedTp").toString());
double playtime = Double.parseDouble(json.get("playtime").toString());
String rank = getRank(averageWpm);

File chart = this.getChart();

channel.sendMessageEmbeds(new EmbedBuilder()
.addField(title,
Expand All @@ -92,7 +107,8 @@ else if (args.length == 3 && args[2].equals("-g"))
Math.floor(playtime / (1000 * 60 * 60)), Math.floor( (playtime / (1000 * 60))%60 ),
rank), false)
.setColor(new Color(180, 50, 80))
.build())
.setImage("attachment://chart.png")
.build()).addFile(chart, "chart.png")
.queue();
}
catch (InterruptedException | NumberFormatException e)
Expand Down Expand Up @@ -130,5 +146,41 @@ private static String getRank(double wpm)

return rank;
}

//TODO: this can likely be abstracted when we want to generate other sorts of charts in the future.
private File getChart() {
try
{

LinkedHashMap<String, Integer> monthlyPlaycount = Database.playcount(idStr);

DefaultCategoryDataset lineChartDataset = new DefaultCategoryDataset();
monthlyPlaycount.forEach((monthStr, count) -> lineChartDataset.addValue(count, "playcount", monthStr));

JFreeChart lineChartObject = ChartFactory.createLineChart(
"Playcount","",
"",
lineChartDataset,PlotOrientation.VERTICAL,
true,true,false);
lineChartObject.removeLegend();

CategoryPlot plot = (CategoryPlot) lineChartObject.getPlot();

plot.getDomainAxis().setCategoryLabelPositions(
CategoryLabelPositions.UP_45);
plot.setDomainGridlinesVisible(true);
plot.setRangeGridlinesVisible(false);
plot.getRenderer().setSeriesStroke(0, new BasicStroke(2.0f));

int width = 640; /* Width of the image */
int height = 380; /* Height of the image */
File lineChart = new File( "LineChart.png" );
ChartUtilities.saveChartAsPNG(lineChart ,lineChartObject, width ,height);
return lineChart;
}
catch (Exception e) {e.printStackTrace();}

return null;
}

}
32 changes: 31 additions & 1 deletion zyenyo-discord/src/main/java/zyenyo/Database.java
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,17 @@
import static com.mongodb.client.model.Sorts.ascending;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.Period;
import java.time.ZoneId;
import java.time.temporal.ChronoField;
import java.time.temporal.ChronoUnit;
import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedHashMap;

import org.bson.Document;
import org.bson.conversions.Bson;
Expand Down Expand Up @@ -363,6 +369,30 @@ public static Document channelCompare(String channelID, String discordId) throws

return results;
}

public static LinkedHashMap<String, Integer> playcount(String discordId) {

AggregateIterable<Document> submittedTests = testsV2.aggregate(Arrays.asList(
Aggregates.match(Filters.eq("discordId", discordId)),
Aggregates.sort(ascending("date"))
));

// needed an insert-ordered map
LinkedHashMap<String, Integer> monthlyPlaycount = new LinkedHashMap<String, Integer>();

for (Document test : submittedTests) {
ZonedDateTime date = test.getDate("date").toInstant().atZone(ZoneId.of("UTC"));
String dateStr = date.getMonth().toString() + " " + String.valueOf(date.getYear());
Integer current = monthlyPlaycount.get(dateStr);
if (current == null) {
monthlyPlaycount.put(dateStr, 1);
} else {
monthlyPlaycount.put(dateStr, current + 1);
}
}

return monthlyPlaycount;
}


public static void recalculateTp()
Expand Down

0 comments on commit e129648

Please sign in to comment.